How to display records with certain date from an editbox using ms access and delphi 7 - ms-access-2007

I have a table in MS Access with a name MembersAccount and one of the field name as DatePaid. I am trying to display records from a date entered in an editbox but the output is not displaying any records at all. This is the code I am using.
if ADOQuery1.Locate('datepaid',edit1.Text,[]) THEN
begin
open;
SQL.Clear;
qry:= 'Select * from MembersAccount WHERE((MembersAccount.[DatePaid])='+edit1.Text+')';
SQL.Add(qry);
Active:= True;
Where am I getting the code wrong? Date entered in the editbox is in dd/mm/yyyy format

Use parts like these (not full code):
editStr := edit.Text;
myDate := StrToDate(editStr);
sqlDate := FormatDateTime('yyyy/mm/dd', myDate);
qry:= 'Select * from MembersAccount WHERE((MembersAccount.[DatePaid]) = #' + sqlDate + '#)';

Related

SQL Date Query using parameters - Delphi

I have an SQL Query (MS Access), and I want to add the Date() function into a parameter, however I get the error: [ODBC Microsoft Access Driver]Data type mismatch in criteria expression.
Here is the code:
Qry.SQL.Text := 'SELECT Bookings.Date, Bookings.WeekDay, Bookings.Shift, Bookings.Start, Bookings.Finish,'
+ ' Bookings.DateFinish, Wards.WardName'
+ ' FROM Bookings'
+ ' INNER JOIN Wards ON Bookings.WardNo = Wards.WardNo'
+ ' WHERE (Bookings.NurseNo=:nurseID) AND (Bookings.Date BETWEEN :dateA AND :dateB)'
+ ' ORDER BY Bookings.Date ASC;';
Qry.Params.ParamByName('dateA').Value := 'Date()';
Qry.Params.ParamByName('dateB').Value := 'Date()+6';
I've also tried Qry.Params.ParamByName('dateA').AsString := 'Date()'; but no luck with that, is there a correct way to do this, or would it actually have to be in the query and not parameterised? The reason I want to do it like this, is I will have multiple different queries based on which button is pressed, but the only thing changing is those parameterised dates.
A parameter can't be a function, it has to be a value. You are assigning strings as those values, and those strings do not represent valid dates. That is why you are getting a mismatch error.
You can use Delphi Date() function, and pass the returned TDate as a parameter value:
Qry.Params.ParamByName('dateA').Value := Date();
Qry.Params.ParamByName('dateB').Value := Date()+6;
Or, you can use Access's Date() function in the SQL itself:
Qry.SQL.Text := 'SELECT Bookings.Date, Bookings.WeekDay, Bookings.Shift, Bookings.Start, Bookings.Finish,'
+ ' Bookings.DateFinish, Wards.WardName'
+ ' FROM Bookings'
+ ' INNER JOIN Wards ON Bookings.WardNo = Wards.WardNo'
+ ' WHERE (Bookings.NurseNo=:nurseID) AND (Bookings.Date BETWEEN Date() AND Date() + 6)'
+ ' ORDER BY Bookings.Date ASC;';

Delphi/Lazarus Filter MSAccess data by SQL Query using DateTimePicker

I would like to filter data from MS Access and get them to the LazReport.
I tried few combinations of code but none of them worked. I am still getting error "Types of data does not equal in critteria expression".
MS Access field is set to Date/Time with format Short Date (01.01.2017).
DateTimePicker is set to YMD (Year, Month, Day).
This is my code:
procedure TForm12.BitBtn1Click(Sender: TObject);
begin
If ListBox1.ItemIndex=0 then
ReportSelected.Caption:=Listbox1.Items[Listbox1.ItemIndex];
If ListBox1.ItemIndex=1 then
ReportSelected.Caption:=Listbox1.Items[Listbox1.ItemIndex];
If ListBox1.ItemIndex=2 then
ReportSelected.Caption:=Listbox1.Items[Listbox1.ItemIndex];
If ListBox1.ItemIndex=3 then
ReportSelected.Caption:=Listbox1.Items[Listbox1.ItemIndex];
If (ReportSelected.Caption='Production Overview') And (DBLookUpListBox1.ItemIndex <> -1) And (CboShift.ItemIndex = 0) then
begin
SQLQuery_ReportShift.Active:=true;
SQLQuery_ReportShift.Close();
SQLQuery_ReportShift.SQL.Text:='SELECT ProductionDate, Shift, AssemblyLine, Product, OperatorsAvailable, ProductionTime, CleanProductionTime, DowntimeTime, GoodParts, ScrapTotal, ScrapRate, QualityRate, Availability, Performance, OEE FROM ProductionInfo WHERE AssemblyLine='''+DBLookUpListBox1.Items[DBLookUpListBox1.Itemindex]+''' AND ProductionDate='''+FormatDateTime('dd/mm/yyyy', DateTimePicker1.Date)+'''';
SQLQuery_ReportShift.Open();
frReport1.LoadFromFile('ProductionOverview.lrf');
frReport1.ShowReport;
end;
If I remember correctly Access uses the date in the order Y/M/D and puts '#' characters around it:
function AccessDate(d:TDateTime) : string;
var
yy,mm,dd : word;
begin
DecodeDate(d, yy,mm,dd);
result := Format('#%d/%d/%d#', [yy,mm,dd]);
end;
As for DateTimePicker to return only date: Turn off time parts by checking dtpHour, dtpMinute and dtpSecond in HideDateTimeParts.

How can I calculate all field and post (SQL/or onCalcFields)

I want to calculate all fields and add a total field. How can I do this? I did this with sql command, but I don't know how to update dbgrid every time.
My code:
procedure TForm1.Button1Click(Sender: TObject);
begin
ADOQuery1.Close;
ADOQuery1.SQL.Text := 'select names,big1,small1,black1,big2,small2,big3,'+
'((big1+small1+black1+big2+small2+big3)*0.35) as total from adlar7v';
ADOQuery1.Open;
end;
when I run this code the first time it works, but the second time the changes don't appear in the grid.
Second method:
I did this with the TAdoQuery.OnCalcField event but there is a problem.
I know how to calculate a field but I don't know how to multiply all field after addition
my code:
ADOQuery1.FieldValues['total'] :=
ADOQuery1.FieldValues['big1'] + ADOQuery1.FieldValues['small1'] +
ADOQuery1.FieldValues['black1'] + ADOQuery1.FieldValues['big2'] +
ADOQuery1.FieldValues['small2'] + ADOQuery1.FieldValues['big3'];
ADOQuery1.FieldValues['cemi']:=((ADOQuery1.FieldValues['boyuk1'] + ADOQuery1.FieldValues['boyuk2'] + ADOQuery1.FieldValues['boyuk3'])*0.35)+((ADOQuery1.FieldValues['kicik1'] + ADOQuery1.FieldValues['kicik2'])*0.25)+(ADOQuery1.FieldValues['qara1']*0.30);
Hi I want to post calc field(cemi) to table (sql). when I calc all field the last field doesn't post on sql table. because last field (cemi) type fkcalc how can I post fkcalc type field Thanks in advance!
when I run this code first time working second time changes doesn't appear db grid
Use the Object Inspector to set up an AfterPost handler on your AdoQuery1:
procedure TForm1.ADOQuery1AfterPost(DataSet: TDataSet);
begin
AdoQuery1.Refresh;
end;
Then, after you save a change to one of the numeric columns in the grid, the AdoQuery1.Refresh will cause the data to be retrieved again from the server, and that will cause the server to recalculate the "Total" column. The fact that it isn't doing that at the moment is why the Total column isn't updating.
Btw, if I've understood what you are asking about that correctly, then your second point
I know how to calculate field but don't know how to multiplication(*) all field after (+)
Use the following code for this
ADOQuery1.FieldValues['total'] := (
ADOQuery1.FieldValues['big1'] + ADOQuery1.FieldValues['small1'] +
ADOQuery1.FieldValues['black1'] + ADOQuery1.FieldValues['big2'] +
ADOQuery1.FieldValues['small2'] + ADOQuery1.FieldValues['big3'] )
* 0.35;

Delphi7 TADOQuery filter not accurate at quick report

i want to show report with date range
i have code
procedure TForm1.ButtonPreviewClick(Sender: TObject);
begin
...
ADOQuery1.Active := False;
ADOQuery1.SQL.Text:='';
ADOQuery1.SQL.Text :='SELECT * FROM tablename WHERE datefield BETWEEN :startdate and :enddate';
ADOQuery1.Parameters.ParamByName('startdate').DataType:= ftdate;
ADOQuery1.Parameters.ParamByName('endate').DataType:= ftdate;
ADOQuery1.Parameters.ParamByName('startdate').value:= datetostr(DateTimePicker1.Date);
ADOQuery1.Parameters.ParamByName('enddate').value:= datetostr(DateTimePicker2.Date) ;
ADOQuery1.Active := True;
QuickRep1.Preview;
...
end;
and i put 4 test records to tablename
number|date
1 |14/8/2015
2 |1/8/2015
3 |31/8/2015
4 |9/8/2015
if i click the button, quick report only showing first record, no matter what date i choose, like this
quickreport
number|date
1 |14/8/2015
with quick report properties
qrband title = qrlabel1 with caption 'quickreport'
qrband column header = qrlabel2 with caption 'number', qrlabel3 with caption'date'
qrband detail = qrdbtext1 & qrdbtext2 with dataset 'adoquery1', datafield 'numberfield' on qrdbtext1 and 'datefield' on qrdbtext2
how to show all data with date range filter?
thanks for your attention

SQL Query fails on empty result

I have a function that performs a query on a SQL database with an ADO connection, it is simply designed to provide a single result for a database entry that can only have one match for a SELECT type of query (i.e. get me the x value from ID 45, where there is and can only be one ID 45 entry).
The function works fine, until I hit a query that returns no results. The query just hangs, and the application cannot continue. Here is an example query string:
'SELECT Cost FROM MaterialCost ' +
'WHERE MaterialType = ''' + 'MS' +
''' AND Thickness = ''' + '0.250' + '''';
Again this exact string will work fine until I maybe query for something that I know before hand doesn't exist, which should return null or an empty string. Here is the function:
function SelectOneQuery(AQueryString : String; AADOConnectionString : String) : String;
var
ADOQuery: TADOQuery;
begin
//Create empty ADO Query, then connect to connection string
ADOQuery := TADOQuery.Create(nil);
ADOQuery.ConnectionString:=AADOConnectionString;
ADOQuery.SQL.Clear;
ADOQuery.SQL.Add(AQueryString);
ADOQuery.ExecSQL;
ADOQuery.Open;
//Set first query result and return first result
ADOQuery.First;
if(ADOQuery.Fields.Count > 0) then begin
result:=ADOQuery.Fields[0].Value;
end
else begin
result := '';
end;
end;
I added the fields count thing, but I'm not sure if that's helping at all. Basically, if there are no result, i want result := ''
You have a few problems in your code snippet:
The main problem is that you are checking FieldCount. FieldCount will always be nonzero because it contains the number of columns your query returns, regardless of the fact your query returned records or not. One option is to check RecordCount which represents the number of rows returned but a better option is to check EOF flag.
you are leaking ADOQuery. Always use try/finally blocks to create and cleanup objects.
ExecSQL is used for queries that don't return recordsets (like INSERT and DELETE),
use Open instead
No need to use First after Open
If you use the same query over and over you are better off using parameters, as a bonus your code will be more readable.
Example:
ADOQuery.SQL.Text := 'SELECT Cost FROM MaterialCost WHERE MaterialType = :MaterialType AND Thickness = :Thickness';
ADOQuery.Parameters.ParamByname('MaterialType').Value := 'MS';
ADOQuery.Parameters.ParamByname('Thickness').Value := 0.25;
Your function code should be something like this:
function SelectOneQuery(const AQueryString, AADOConnectionString: string): string;
var
ADOQuery: TADOQuery;
begin
Result := '';
ADOQuery := TADOQuery.Create(nil);
try
ADOQuery.ConnectionString := AADOConnectionString;
ADOQuery.SQL.Text := AQueryString;
ADOQuery.Open;
if not ADOQuery.EOF then
Result := ADOQuery.Fields[0].AsString;
finally
ADOQuery.Free;
end;
end;