(Delphi) query.next not working - delphi

I need help to fix my code...
I try to build some application with this code
Adoquery.close;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select * from schedule where every like ''%5%''');
ADOQuery1.Open;
if not ADOQuery1.Eof then
begin
ShowMessage('hallo '+ADOQuery1.fieldbyname('remark').AsString);
ADOQuery1.Next;
end
Else
Begin
end;
I have 2 data records for the result, but why only one remark is showing?
I try to Trace it and found problem in ADOQuery1.next. After my application read ADOQuery.next, cursor jump to end; not go back to if not ADOQuery1.Eof then.
Any mistakes with my code?

The execution does not go back to the if statement because the code does not say to do so. You have a single if statement and no iteration. You need to iterate. For instance with a while loop:
while not ADOQuery1.Eof do begin
// do something
ADOQuery1.Next;
end;

Related

Why am I getting this error with OTL?

I am using OTL for the first time and I was trying to use the Async/Await abstraction.
Now, I created a small program just to see what will happen. It's just a button and it calls this procedure.
procedure TForm2.Button1Click(Sender: TObject);
var i : integer;
begin
Button1.enabled := false; //Only for second try
for i := 0 to 100 do
begin
Async(
procedure begin
sleep(5000);
end).
Await(
procedure begin
//First Try - Button1.Enabled := true;
//Second Try - showmessage('finished')
end
);
Button1.enabled := true; //Only for the second try.
end;
end;
First Try
For this it works fine the first time, disable the button, sleep for the asyncs and then enable it back.
But the second time I click the button, it is disabled but never gets enabled again.
Second Try
This time I wanted to show a message x100 times and it works the first time aswell, but when I call the procedure again I get the following error TOminCommunicationEndpoint.Send: Queue is full
Can someone who has used this library explain to me, why am I getting this error? And if it is related to the problem with the first try?
It seems you are hitting an internal limitation of OTL.
Each call to Async-Await starts a new thread and returns immediately. When the loop is done you end up with 100 threads, each waiting 5 seconds before executing the Await code.
AFAIK, there is a limitation of 60 concurrent threads in OTL when using the threadpool.

Stackoverflow error (infinite loop) while using Devexpress VCL 13.1.2

I am using TcxGridDBBandedTableView and have two columns of type TcxGridDBBandedColumn.
vwABC : TcxGridDBBandedTableView
vwABCField1 : TcxGridDBBandedColumn
vwABCField2 : TcxGridDBBandedColumn
When I change anything in vwABCField1, vwABCField2 values should get cleared. For this I am using OnEditValueChanged property of vwABCField1 like this:
procedure TMyForm.vwABCField1PropertiesEditValueChanged(Sender: TObject);
begin
vwABCField2.EditValue := '';
end;
While debugging, when I come to vwABCField2.EditValue := ''; statement, I never return back and get trapped in infine loop and after some time I get stackoverflow error.
vwABCField2.EditValue := ''; is calling vwABCField1PropertiesEditValueChanged procedure again and again recursively infinite time. I don't know why. I have not declared anything on OnEditValueChanged event of vwABCField2.
Update
If I write anything else in the above function instead of vwABCField2.EditValue := '';, it will be called only once. For example
procedure TMyForm.vwABCField1PropertiesEditValueChanged(Sender:TObject);
begin
ShowMessage("hi");
end;
works fine. So I suspect that culprit is vwABCField2.EditValue := ''; statement.
As in the official documentation is stated:
Do not change the edit value in your OnEditValueChanged event handler, as this can result in stack overflow. Use this event to get notification that the edit value has changed.
Because when you change the edit value in this event, of course, your editvalue is changed and therefore calling the OnEditValueChanged event again and again and ...

Why is except not catching this error?

I have a program that simulates dice rolls and compares them to values in a chart (set of String lists). I currently get the value from a TEdit. If the box is empty it raises a EConvertError that should be caught by my Try/Except statement, but it's not. Thoughts and advice? Code below, Delphi 7.
try
//Shooting
if ShootingRadio.Checked then
BS := StrToInt(Edit1.Text);
Randomize;
Roll := RandomRange(1,7);
Label3.Caption := IntToStr(Roll);
if (Roll < StrToInt(ShootingHitChart[BS-1])) then
begin
Label3.Caption := (IntToStr(Roll)+' Miss');
RichView1.AddTextNL((IntToStr(Roll)+' Miss'),7,0,1);
RichView1.Reformat;
end
else
begin
Label3.Caption := (IntToStr(Roll)+' Hit');
RichView1.AddTextNL((IntToStr(Roll)+' Hit'),6,0,1);
RichView1.Reformat;
end;
except
MessageBox(0,'No number entered.','Error',mb_OK);
end;
'Stop on Delphi exceptions' is checked in the debugger options. The exception is actually caught just fine, but the IDE stops when you get it. When you continue running, you will not see the exception, but your message instead. Out of the IDE it will run fine.
You can uncheck this option (I usually do). You can always re-check it when you need to debug some stubborn problem.

Problem with running WebService in separate thread in Delphi

I have never asked questions in any community as I always solved problems by myself or could find them online. But with this one I came to dead end and need Help!
To make it very clear – I converted a simple app, found elsewhere to make it use a Tthread object.
The idea is simple – the app checks online using webservice, through THTTPRIO component, weather and put the results in Memo1 lines.
Clicking on Button1 we get it done in standard way – using THTTPRIO put on the Form1 (it's called here htt as in original app) and using main and only thread.
procedure TForm1.Button1Click(Sender: TObject);
var
wf:WeatherForecasts;
res:ArrayOfWeatherData;
i:integer;
begin
wf:=(htt as WeatherForecastSoap).GetWeatherByPlaceName(edit1.Text);
if wf.PlaceName<> '' then
res:=wf.Details;
memo1.Lines.Add('The min and max temps in Fahrenheit is:');
memo1.Lines.Add(' ');
for i:= 0 to high(res) do
begin
memo1.Lines.Add(res[i].Day+' - '+ ' Max Temp. Fahr: '+res[i].MaxTemperatureF+' - '+'Min Temp Fahr: '+res[i].MinTemperatureF);
end
end;
Clicking on Button2 – we use class TThread
procedure TForm1.Button2Click(Sender: TObject);
var WFThread:WeatherThread;
begin
WFThread := WeatherThread.Create (True);
WFThread.FreeOnTerminate := True;
WFThread.Place := Edit1.Text;
WFThread.Resume;
end;
In Execute procedure in WeatherThread1 unit I put this code:
procedure WeatherThread.Execute;
begin
{ Place thread code here }
GetForecast;
Synchronize (ShowWeather);
end;
...and the GetForecast code:
procedure WeatherThread.GetForecast;
var
HTTPRIO: THTTPRIO;
wf:WeatherForecasts;
res:ArrayOfWeatherData;
i:integer;
begin
HTTPRIO := THTTPRIO.Create(nil);
HTTPRIO.URL := 'http://www.webservicex.net/WeatherForecast.asmx';
HTTPRIO.WSDLLocation := 'http://www.webservicex.net/WeatherForecast.asmx?WSDL';
HTTPRIO.Service := 'WeatherForecast';
HTTPRIO.Port := 'WeatherForecastSoap';
wf:=(HTTPRIO as WeatherForecastSoap).GetWeatherByPlaceName(Place);
if Lines=nil then Lines:=TStringList.Create;
if wf.PlaceName<> '' then
res:=wf.Details;
Lines.Clear;
for i:= 0 to high(res) do
begin
Lines.Add(res[i].Day+' - '+ ' Max Temp. Fahr: '+res[i].MaxTemperatureF+' - '+'Min Temp Fahr: '+res[i].MinTemperatureF);
end;
end;
Procedure ShowWeather shows results in Form1.Memo1.
And now there is a problem: In main thread, clicking Button1, everything works fine. But of course when HTTPRIO component communicates – it freezes the form.
With Button2 I put the code in separate thread but it does NOT WANT TO WORK! Something strange happens. When I start application – and click Button2, there is an error when using HTTPRIO component. But it works for a while when I click FIRST Button1 and AFTER THAT Button2 (but it works for a while, 5-7 clicks only).
I suppose I do something wrong but cannot figure out where the problem is and how to solve it. It looks like the code in threaded unit is not thread-safe, but it should be. Please help how to make HTTPRIO work in a thread!!!
You can find zipped full code here.
When I run your code in Delphi 2007, madExcept shows an exception CoInitialize has not been called.
After adding the call to CoInitialize in the execute method, the webservice gets called without problems.
Possible fix
procedure TWeatherThread.Execute;
begin
CoInitialize(nil);
try
...
finally
CoUninitialize;
end;
end;
A long shot, but I'm missing calls to Synchronize here:
You should never update your GUI directly from your thread code.
You should embed those calls inside a method, and call that method using the TThread.Synchronize method for this.
Delphi about has a nice demo on this.
Since Delphi 4, it includes a demo called sortthds.pas in the ...\demos\threads subdirectory that shows the same.
--jeroen
You may be clouding the issue by doing the dynamic RIO creation (RIO objects have a strange lifetime) and threading together, and comparing that outcome to the straightforward Button1. I'd make another button that calls GetForecast without threads. See if that works. If it bombs, then your problem isn't threading.

how to pause while some process going in loopss(delphi)

how can i pause and resume in application while working with loops
i can put some sleep(xxx) at begininsg of my loop to pause ,but i want pause when ever i want and resume when i ever i need
any ideas ?
thanks in advance
ok here is alittle more explanation
for i:=0 to 100 do
begin
if button1.clicked then pause //stop the operation and wait for resume button
if button2.clicked then resume //resume the operations
end;
edit2 :
ok guys i will tell an example well take any checker for suppose proxy checker ,i have a bunch of proxies loaded in my tlistviwe i am checking them all ,by using lop for i:=0 to listview.items.count do ......
i want to pause my checking operation when ever i want and resume when ever i need
am i clear or still i have to explain some ? :S
regards
You need a boolean flag that will indicate whether it's safe to continue looping. If something happens that makes it so you need to pause, it should set the variable to false. This means that, unless you're working with multiple threads, whatever sets this flag will have to be checked inside the loop somewhere. Then at the top (or the bottom) of your loop, check to see if this variable is true and pause otherwise.
Here's the basic idea, in the context of your explanation:
procedure TForm1.DoLoop;
begin
FCanContinue := true;
for i:=0 to 100 do
begin
//do whatever
Application.ProcessMessages; //allow the UI to respond to button clicks
if not FCanContinue then Pause;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
FCanContinue := false;
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
FCanContinue := true;
Resume;
end;
This is a very simplistic implementation. What you really should do if you have a long-running task that you need to be able to pause and resume on command is put this in a separate thread and take a look at the TEvent class in SyncObjs.
OK, I don't understand what you are trying to do, but here is some pseudo code:
for i:=0 to 100 do
begin
if button1.clicked then
begin
while not button2.clicked do
sleep(50);
end;
end;
Check if a key is pressed?

Resources