将错误的记录信息发布到表 [英] Posting wrong record information to table

查看:55
本文介绍了将错误的记录信息发布到表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在遍历我的客户表并根据地址发布纬度和经度值时,第一组经度/纬度值将发布到记录编号1和2,然后随后将其后的每条记录都减一.在调试模式下单步执行时,我看到第二条迭代中的第一条记录的值仍然存在.此后,它会自行更正,但是每个记录值都是针对该地址或该地址上方的记录的.为什么?

While looping through my customer table and posting latitude and longitude values based on an address, the first set of lat/lng values are posting to records number 1 and 2, and then subsequently every record thereafter is off by one. When I step through in Debug mode I see that the values for the first record are still there on my second iteration. After that, it corrects itself, but every records values are for the address or record above it. Why?

这是我的代码:

procedure TViewMaps.StartBtnClick(Sender: TObject);
var
  iRecs, i : Integer;
  Location : TLocation;
begin
  ViewMaps := TViewMaps.create(self, MapAddress);
  Customer.Open;
  iRecs:= Customer.RecordCount;
  i := 0;
  While Not Customer.EOF do
    begin
      i := i + 1;
      Customer.Edit;
      MapAddress := CustomerSAddress1.AsString + ' ' + CustomerSAddress2.AsString + ' ' + CustomerSAddress3.AsString + ' ' + CustomerSAddress4.AsString + ', ' + CustomerSCity.AsString + ', ' + CustomerSState.AsString + ' ' + CustomerSZip.AsString;

      fAddress := StringReplace(StringReplace(Trim(MapAddress), #13, ' ', [rfReplaceAll]), #10, ' ', [rfReplaceAll]);
      Location := GetGeoCode(fAddress);

      Customerlat.AsString := Location.Lat;
      Customerlng.AsString := Location.Lng;

      StatusBar1.SimpleText:= 'Update Geocode for address ' + ' [Count ' + IntToStr(i) + ' of ' + IntToStr(iRecs) + ']';
      Sleep(3000);
      StatusBar1.Refresh;
      Customer.Next;
    end;
end;

好的,我根据您的建议修改了代码(不确定我的做法是否正确),但是我得到的结果完全相同.该程序只是一个运行一次的应用程序,用于将纬度/经度值填充到我们的数据库中,而延迟是因为我遇到了Google查询限制,并且该应用程序在从Google返回结果之前就将其发布到了数据库中,所以我必须减慢它的速度.

Okay, I modified the code based on your suggestion (not sure I'm doing it the right way), but I'm getting the exact same result. This program is just a run once application to populate the lat/lng values to our database, and the delay is because I was running into a Google query limit and the app was posting to the database before the results were back from Google, so I had to slow it down.

这是更新的代码:

procedure TViewMaps.StartBtnClick(Sender: TObject);
begin
  Customer.Open;
  iRecCount:= Customer.RecordCount;
  iCurRec := 0;
  Customer.First;
  if Not Customer.EOF then Timer1.Enabled := True;
end;

procedure TViewMaps.OnTimer(Sender: TObject);
begin
  iCurRec := iCurRec + 1;
  //ShowMessage('I am here and iCurRec = ' + inttostr(iCurRec));
  Customer.Edit;
  // Load full customer address into MapAddress
  MapAddress := CustomerSAddress1.AsString + ' ' + CustomerSAddress2.AsString + ' ' + CustomerSAddress3.AsString + ' ' + CustomerSAddress4.AsString + ', ' + CustomerSCity.AsString + ', ' + CustomerSState.AsString + ' ' + CustomerSZip.AsString;
  fAddress := StringReplace(StringReplace(Trim(MapAddress), #13, ' ', [rfReplaceAll]), #10, ' ', [rfReplaceAll]);
  // Get Longitude and Latitude from Google Maps
  Location := GetGeoCode(fAddress);
  // Populate lat and lng fields in Customer table
  Customerlat.AsString := Location.Lat;
  Customerlng.AsString := Location.Lng;
  // Post record to Customer table
  Customer.Post;
  StatusBar1.SimpleText:= 'Update Geocode for address ' + ' [Count ' + IntToStr(iCurRec) + ' of ' + IntToStr(iRecCount) + ']';
  StatusBar1.Refresh;
  // Grab the next record in the Customer table
  Customer.Next;
  if Customer.EOF then Timer1.Enabled := False;
end;

好吧...这是codeAddress javascript

Ok... here's the codeAddress javascript

''+
'  function codeAddress(address) { '+
'    if (geocoder) {'+
'      geocoder.geocode( { address: address}, function(results, status) { '+
'        if (status == google.maps.GeocoderStatus.OK) {'+
'          map.setCenter(results[0].geometry.location);'+
'          var myLatlng = new google.maps.LatLng( results[0].geometry.location.lat(), results[0].geometry.location.lng()); '+
'          var marker = new google.maps.Marker({ '+
'            position: myLatlng, '+
'            title: "", '+
'            map: map '+
'          }); '+
'        markersArray.push(marker); '+
'        document.getElementById("hiddenlat").value = myLatlng.lat(); '+
'        document.getElementById("hiddenlng").value = myLatlng.lng(); '+
' '+
'        } else {'+
'            document.getElementById("hiddenlat").value = "error"; '+
'            document.getElementById("hiddenlng").value = "error"; '+
'           alert("Geocode was not successful for the following reason: " +    status);'+
'        }'+
'      });'+
'    }'+
'  }'+
''+

这是Delphi代码:

And here's the Delphi code:

constructor TViewMaps.create(AOwner: TComponent; AAddress: string);
begin
  inherited create(AOwner);
  fAddress := AAddress; // fAddress is now stored to form variable
end;

procedure TViewMaps.LoadGoogleApi;
var
  aStream: TMemoryStream;
begin
  WebBrowser1.Navigate('about:blank'); //Set the location to an empty page
  MemoAddress.Lines.Text := '1600 Amphitheatre Parkway, Mountain View, CA 94043';
  if Assigned(WebBrowser1.Document) then
  begin
    aStream := TMemoryStream.Create; //create a TStream to load the Page from the string
    try
      aStream.WriteBuffer(Pointer(HTMLStr)^, Length(HTMLStr));
      aStream.Seek(0, soFromBeginning);
      (WebBrowser1.Document as IPersistStreamInit).Load(TStreamAdapter.Create(aStream));
    finally
      aStream.Free;
    end;
    HTMLWindow2 := (WebBrowser1.Document as IHTMLDocument2).parentWindow;
  end;

  while WebBrowser1.ReadyState <> READYSTATE_COMPLETE do // wait for google
  begin
    sleep(0);
    application.processmessages;
  end;
end;

function TViewMaps.GoogleApiReady: boolean;
begin
  result := (HTMLWindow2 <> nil);
end;

procedure TViewMaps.ExecuteScript(AScript: string);
begin
  HTMLWindow2.execScript(AScript, 'JavaScript');
end;

function TViewMaps.GetElementByID(AElementID: string): IHTMLElement;
begin
  result := (WebBrowser1.Document as IHTMLDocument3).getElementByID(AElementID);
end;

function TViewMaps.GetElementValue(ElementID: string): string;
var
  HtmlElement: IHTMLElement;
begin
  HtmlElement := GetElementByID(ElementID);
  result := HtmlElement.getAttribute('value', 0);
end;

procedure RemoveInvalidGeoLookupChars(var AString: string);
begin
  AString := StringReplace(StringReplace(Trim(AString), #13, ' ', [rfReplaceAll]), #10, ' ', [rfReplaceAll]);
  // remove invalid chars
  AString := StringReplace(AString, #39, #32, [rfReplaceAll]);  // single quotes
  AString := StringReplace(AString, #34, #32, [rfReplaceAll]);  // double quotes
end;

procedure TViewMaps.FormShow(Sender: TObject);
var
  Location: TLocation;
begin
  MapAddress := '1600 Amphitheatre Parkway' + ', ' + 'Mountain View' + ', ' + 'CA' + ' ' + '94043';
  ViewMaps := TViewMaps.create(self, MapAddress);
  LoadGoogleApi;
  address := MemoAddress.Lines.Text;
  fAddress := StringReplace(StringReplace(Trim(address), #13, ' ', [rfReplaceAll]), #10, ' ', [rfReplaceAll]);
  Location := GetGeoCode(fAddress);
  LatitudeEdit.Text := Location.Lat;
  LongitudeEdit.Text := Location.Lng;
end;

function TViewMaps.GetGeocode(Address: string): TLocation;
begin
  result.Lat := '0';
  result.Lng := '0';
  LatitudeEdit.text := '0';
  LongitudeEdit.text := '0';
  result.Result := 'OK';
  application.processmessages;
  RemoveInvalidGeoLookupChars(address);
  application.processmessages;
  ExecuteScript(Format('codeAddress(%s)',[QuotedStr(Address)]));

  while (GetElementValue('hiddenlat') = '0') do
    application.processmessages;

  result.Lat := GetElementValue('hiddenlat');
  result.Lng := GetElementValue('hiddenlng');
end;

procedure TViewMaps.StartBtnClick(Sender: TObject);
var
  iRecCount, iCurRec: integer;
  Location: TLocation;
  fAddress, MapAddress: string;
begin
    Customer.open;
    Customer.first;
    iRecCount := Customer.RecordCount;
    iCurRec := 0;
    while not Customer.eof do
    begin
      inc(iCurRec);
      fillchar(Location, sizeof(Location), 0);
      MapAddress := CustomerSAddress1.asstring+' '+CustomerSAddress2.asstring+' '+CustomerSCity.asstring+', '+CustomerSState.asstring+' '+CustomerSZip.asstring;
      fAddress := StringReplace(StringReplace(Trim(MapAddress), #13, ' ', [rfReplaceAll]), #10, ' ', [rfReplaceAll]);
      fillchar(Location, sizeof(Location), 0);
      Location := GetGeocode(fAddress);
      if (Location.lat <> 'error') and (Location.lat <> '0') then
      begin
        Customer.edit;
        CustomerLat.AsString := Location.Lat;
        CustomerLng.AsString := Location.Lng;
        Customer.Post;
      end;
      Statusbar1.SimpleText := 'Update Geocode for address ' + ' [Count ' + IntToStr(iCurRec) + ' of ' + IntToStr(iRecCount) + ']';
      application.processmessages;
      sleep(2000); // adjust to not exceed Google API query limit
      Customer.next;
    end;
end;

推荐答案

SO用户应该知道这是OP先前问题之一的延续-

Users of SO should know that this is a continuation to one of OP's previous questions - Getting Latitude Longitude from GoogleMaps in TWebBrowser

我使用下面的代码创建了一个测试.我的客户表字段名称不同,但是您会明白的.

I created a test using the code below. My customer table field names are different, but you'll get the idea.

请注意,尽可能缩短Customer.edit和Customer.post之间的时间,以免过早发布.另外,请确保客户"表中没有任何会导致循环中断的事件.仅在返回有效的地理编码后才进行编辑/发布.而且,为了达到良好的效果,位置记录会在每次迭代时初始化.

Notice to keep the time between Customer.edit and Customer.post as narrow as possible, to avoid any premature posts. Also, make sure that Customer table doesn't have any events that would cause an interruption during your loop. Only edit/post if a valid geocode has been returned. And for good measure, the Location record is initialized at each iteration.

procedure TForm2.StartBtnClick(Sender: TObject);
var
  iRecCount,
  iCurRec: integer;
  Location: TLocation;
  fAddress, MapAddress: string;
begin
    Customer.open;
    Customer.first;
    iRecCount := Customer.RecordCount;
    iCurRec := 0;
    while not Customer.eof do
    begin
      inc(iCurRec);
      fillchar(Location, sizeof(Location), 0);
      MapAddress := CustomerAddress.asstring+' '+CustomerAddress2.asstring+' '+CustomerCity.asstring+', '+CustomerState.asstring+' '+CustomerZip.asstring;
      fAddress := StringReplace(StringReplace(Trim(MapAddress), #13, ' ', [rfReplaceAll]), #10, ' ', [rfReplaceAll]);
      fillchar(Location, sizeof(Location), 0);
      Location := form1.GetGeocode(fAddress);
      if (Location.lat <> 'error') and (Location.lat <> '0') then
      begin
        Customer.edit;
        CustomerLatitude.AsString := Location.Lat;
        CustomerLongitude.AsString := Location.Lng;
        Customer.Post;
      end;
      Statusbar1.SimpleText := 'Update Geocode for address ' + ' [Count ' + IntToStr(iCurRec) + ' of ' + IntToStr(iRecCount) + ']';
      application.processmessages;
      sleep(1000); // adjust to not exceed Google API query limit
      Customer.next;
    end;
end;   

此外,修改您的codeAddress Javascript函数以清除隐藏的页面值.

Also, modify your codeAddress Javascript function to clear the hidden page values.

''+
'  function codeAddress(address) { '+
'    document.getElementById("hiddenlat").value = "0"; '+
'    document.getElementById("hiddenlng").value = "0"; '+
'    if (geocoder) {'+
'      geocoder.geocode( { address: address}, function(results, status) { '+
'        if (status == google.maps.GeocoderStatus.OK) {'+
'          map.setCenter(results[0].geometry.location);'+
'          var myLatlng = new google.maps.LatLng( results[0].geometry.location.lat(), results[0].geometry.location.lng()); '+
'          var marker = new google.maps.Marker({ '+
'            position: myLatlng, '+
'            title: "", '+
'            map: map '+
'          }); '+
'        markersArray.push(marker); '+
'        document.getElementById("hiddenlat").value = myLatlng.lat(); '+
'        document.getElementById("hiddenlng").value = myLatlng.lng(); '+
' '+
'        } else {'+
'            document.getElementById("hiddenlat").value = "error"; '+
'            document.getElementById("hiddenlng").value = "error"; '+
'           alert("Geocode was not successful for the following reason: " +    status);'+
'        }'+
'      });'+
'    }'+
'  }'+
''+

这篇关于将错误的记录信息发布到表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆