close to 3 months into powerbuilder classic 12.5 and sql server 2008 and am working out well. I am creating a car hire system using car registration_number as the primary key.
i need to capture the car's details and make sure that the registration_number is not available. The code here is not working but that of the capacity works out...
What is wrong with the code? please give another way that works.
if i dont click on the column 'capacity' and click on save, the program goes on and saves the record even when it is an empty field. how to i avoid that.
String car_registration_number
car_registration_number = dw_newvehicle.GetItemString( Row, "registration_number" )
long error_code = 0
string column
column = dwo.name
choose case column
case "registration_number"
if data = car_registration_number THEN
messagebox("validation error", "You cannot available regno")
error_code = 1
end if
case "capacity"
if integer(data) >10 then
messagebox("validation error", "a car's capacity cannot be more than 10...")
error_code = 1
end if
end choose
return error_code
Instead of GetItemString at the top, you would need to do one or two finds in the DataWindow for the registration number in data. If the first find returns 0 you are OK. If it returns the current row, you need to search from row to the last row unless you are on the last row, which you may well be if you are inserting. However, I wouldn't do it that way because it won't work in a multi-user environment. Instead, you should go ahead and insert the row and then if you get a duplicate key error, tell the user the registration number is already in the system. If the user is going to enter a lot of data you could try to SELECT the registration number from the database when the user enters it, but you still have to be able to handle the duplicate key error.
I don't understand what kind of check you are doing here for registration_number : you are getting the current value of the column in the DW into car_registration_number then you are comparing to the value that was modified (the code comes from the itemchanged event ?). Do you expect to enter a value that is different from the current one ?
Also beware of the GetItemString if the type of the column is not a text (as it is called ..._number) as PB may crash, return some null value or silently fail (depending on the PB mood of the moment ;). If you get a null value, your if check will always fail.
If you want to get numerical values, use GetItemNumber instead.
you can set the capacity column to be not null in you database. When saving the DW, you will get an error telling that there is some required value that was not set.
A better idea would be to iterate in the UpdateStart event on the columns that are member of the table primary key and to check if they are set or not.
To write some dynamic code, you can get at runtime the columns from the DW by describing the datawindow.column.count then checking the pk members with #1.key (replace #1 by #2, #3, ...) if the check must be done on that column.
Related
I have an Asterisk cdr database with rows representing every "call" (it's actually multiple rows per call depending on if it's inbound, outbound, local) executed inside my office.
I have 3 extensions (200, 201, 202) so for every inbound call asterisk generates 3 rows with the same 'uniqueid' and a 'disposition' indicating whether said extension answered or not a said call.
I utilize this data to generate a Call History listview for a small desktop program running on every desk and I need to show only the calls of a given extension and FROM HERE stems my question:
I should show every inbound call of my extension BUT if a call disposition is 'NO ANSWER' BUT STILL someone else answered that specific call i shoudn't show the call since it is not actually missed; to say it in other words, I should show a call missed only if EVERY extension missed it (has NO ANSWER disposition).
I thought of flagging a row with a bool field conditioned on whether or not there is at least one row with the same 'uniqueid' that has disposition 'ANSWER'. I added the column 'isToDiscard' but I don't now how to go on; maybe triggers could be used but i couldn't do it.
Am I approaching the problem in a meaningful way? I kinda did this in the backend but this flag or approach whould make everything easier.
We can identify the non-answered calls with a window function:
select *
from (
select c.*,
max(disposition = 'ANSWERED') over(partition by uniqueid) as was_answered
from cdr c
) c
where was_answered = 0
Expression disposition = 'ANSWER' returns 1 if the value matches, else 0 : taking the maximum of that value over a group of calls (as identify by a partition rows sharing the same uniqueid) tells us if the call was answered by any desk. We can the use that information to filter.
If you want to filter the resultset for a specific desk (extension), then you can simply add the filter to the outer query.
As the subject expresses, I'm trying to sum the values of a string field where spaces may exist. It must be done this way, unfortunately.
The database is very old. The original developer chose to make all fields Text fields; to get over the null value problems, a function was written in VB6 to replace any null value with a space. This cannot be changed.
Fast forward to now, I'm trying to create a report that sums the length field without changing spaces to nulls first, and it should be done entirely through the control source property of the report.
I've added some of what I've tried below, but every time the report is run, I receive:
Data Type Mismatch
...and I'm not sure how to get around it.
Ideally, I'd like to keep the users out of the database completely, and just add a combo box that lists the reports created in the database so they can be opened by name without having to run any additional update queries first.
=Sum(IIf([MY_LEN]<>" ",DCount("[MY_LEN]","MY_TABLE"),0))
=Sum(Nz(Iif(Trim([MY_LEN])='',Null,[MY_LEN]),0))
=DSum("[MY_LEN]","[MY_TABLE]","[MY_LEN]<>' '")
=Sum(Iif(Val([MY_LEN])>0,[MY_LEN],0))
=(SELECT Sum([MY_LEN]) AS MyLen FROM MY_TABLE WHERE (((MY_TABLE.[MY_LEN])<>' ')))
Is this possible?
Can't compare anything to Null. Can't say If x = Null Then because Null is undefined. So you can't test if undefined = undefined. Use If IsNull(x) Then in VBA and Is Null in query criteria. Don't really need IIf() for Sum() aggregate, other aggregates such as Count or Avg would.
To handle possible space, empty string, or Null for a text field holding numeric data.
=Sum(Val([MY_LEN] & ""))
I am trying to make a query for approval of documents, where the result display the name and signature with date. How can I get the date for two people approving the document?
Select Uname
case when stepcode=1 then 'approver1' end as 'name of person'
case when stepcode=1 then 'approver1' end as ' date of signed noted'
case when stepcode=2 then 'approver2' end as 'date of signed approved'
from table
I tried this, but only one result showed up. Only the name, signature and date of the first approval displayed.
We can only answer this by making some assumptions:
the field stepcode denotes what stage of the sign off process the record is at
value of 1 means noted and value 2 means approved. A value of 0 means nothing has happened yet
approver1 and approver 2 are NULL if the action has not yet taken place
If all of the above is true, then there should be no requirement to have a CASE statement for the fields... just including the fields within the SELECT statement will bring the values through if they have been completed.
Some validation of data might be required here though if you are not getting the results you are expecting. Running some rough counts for each of the steps and for where they have values in the approver fields would help to make sure your code is working. The following should give you something to work with:
SELECT
stepcode
COUNT(TableID) AS NumberAtStep
FROM table
GROUP BY stepcode
Using these counts, you can then run your statement without the CASE statements and run a manual count to ensure you are seeing the right number of records with the relevant populated columns for each step.
Further information will be required to delve into your problem further however
I am attempting to maintain and fix a horribly out-of-date CRM designed by an ex-employee ~4-5 years ago in Access 2007. I have brought it into Access 2013 and fixed a ton of stuff up, but I am still running into many problems.
I spent a good 4 hours today attempting to figure out why certain values didn't line up. These values were being pulled from a SELECT statement on a Combo Box over a stored Query which simply returns a table with a few extra rows. Great.
However this value (a number) doesn't appear to correlate with what we expect. I enter in one value, save the ticket, and a completely different value gets stored into the table. Opening up the ticket, I see the value that I expect. Digging deeper, I found the following difference:
Set value_1 = Me.RegistrationID // What's being stored in the table
Set value_2 = Me.RegistrationID.Column(0) // What we expect
Surprise surprise! This is a Combo Box and some value is being stored in the table. The Control Source is "RegistrationID" and the Row Source is the query in question.
However I do not know what it is! This specific value correlating to the Combo Box appears to pull the correct data when we later open the tickets. However I have a strong feeling that this could be why many tickets from before one of the rows was deleted all appear to have invalid RegistrationID's.
How badly can this break?
How easily can we correct tens of thousands of tickets?
How can I fix this to store the correct value?
This is what I expect is happening.
Your combo box row source is based on a Select query which returns and displays multiple rows. For example:
Select RegistrationID, CustomerID, CustomerName From MyTable;
The Control Source for the combo box is bound to RegistrationID which is part of the Forms Record Source.
The issue is the bound column. If we set the bound column in our example to 1, then we get the behavior your are describing with:
Set value_1 = Me.RegistrationID - Set's value to CustomerID (may appear correct)
Set value_2 = Me.RegistrationID.Column(0) - position 0 from our query (RegistrationID)
Further building on our query example, you can say:
Me.TextBox1 = Me.RegistrationID.Column(0) - RegistrationID
Me.TextBox2 = Me.RegistrationID.Column(1) - CustomerID
Me.TextBox3 = Me.RegistrationID.Column(2) - CustomerName
The RegistrationID is what normally should be stored in the table.
As long as your form shows any values that directly relate to this RegistrationID you're fine.
I would start by checking to see under the format setting to see if column widths are set properly and I would also check under the data section to see if the bound column is correct. I might also throw in an after update macro/vba sub routine that saves the record. Hope this helps.
I am trying to build a query which will look at the data in two fields in two different tables and check to see if the data is the same, if it is I want it to return the number of times it is matched, if it isn't I simply want it to return the text saying "No viewings".
I have constructed this query in my access database which has the field from the first table "Property" and the second field I want it to compare the data with, "Viewings". I have build the following expression using the build tool, however I am stuck to make it work since every time I get this error message when trying to run the query: "Your query does not include the specified expression 'Property Viewed' as part of an aggregate function."
totalViewings: IIf([Viewings]![Property Viewed]=[Property]![ID],Count([Viewings]![Property Viewed]=[Property]![ID]),"No Viewings")
Any help how to overcome this error would be very appreciated.
Thanks
I would suggest doing something like this:
1) Assuming this is something you are developing yourself, make sure your data structure is all in order first. Since I dislike relatively code-hostile identifiers, I'd have the tables as so -
Properties - PropertyID (AutoNumber, primary key), HouseNumberOrName, Street, etc.
Viewings - ViewingID (AutoNumber, primary key), PropertyID (Number/Long Integer), ViewingDate, etc.
In the Relationships view, Properties.PropertyID would then be set up to point to Viewings.PropertyID in a one-to-many relation.
2) Your actual query I would then break into two, the first to compile the data and the second to format it for display. The first would go like this, saved as ViewingCounts...
SELECT Properties.PropertyID, Count(Viewings.PropertyID) As ViewingCount
FROM Properties LEFT JOIN Viewings ON Properties.PropertyID = Viewings.PropertyID
GROUP BY Properties.PropertyID;
... and the second like this, saved as ViewingCountsForDisplay:
SELECT Properties.*, IIf(ViewingCount = 0, 'No viewings', ViewingCount) AS Viewings
FROM Properties INNER JOIN ViewingCounts ON Properties.PropertyID = ViewingCounts.PropertyID
ORDER BY Properties.PropertyID;