EAccessViolation - program do pobierania linków

0

Witam! Tworzę program do pobierania linków ze strony, używam WebBrowsera jako komponentu do wyświetlania stron. Wszystko idzie dobrze, tylko jest jeden kłopot. Robię pętlę która zapisuje linki po kolei do tablicy i wyświetla w RichEdit (Link: array[1..160] of String;):

for i := 1 to 160 do
    begin
      Link[i] := WebBrowserChom.OleObject.Document.Links.Item(i).href;
      RichEditTekst.Lines.Add(Link[i]);
    end;

Problem pojawia się właśnie gdy zaczyna się wykonywanie pętli. Wyświetla się komunikat:

Project CHRMultiSender.exe raised exception class EAccessViolation with message 'Access violation at address 0045A84B in module 'CHRMultiSender.exe'. Read of address 00000000'. Process stopped. Use Step or Run to continue.

I debugger zaznacza mi w kodzie linię Link[i] := WebBrowserChom.OleObject.Document.Links.Item(i).href; Co ciekawe, jeszcze wczoraj kiedy miałem odliczanie od 1 do 160 działało mi, a teraz mam ten bład. A dzisiaj, kiedy zmienię na odliczanie do 150 to błędu nie wyświetla i wypisuje mi normalnie linki do RichEdita. Co to może być, i jak się tego pozbyć? Ten kod znajduje się w procedurze WebBrowsera OnDocumentComplete.

0

Może dlatego, że linków jest tylko 150 ?
A ty chcesz mieć 160.

0

zazwyczaj indeksowanie wszysktiego zaczyna sie od 0. Ty zaczynasz w swojej tablicy od 1.
albo indeksuj swoja tablice od 0 albo daj:

      WebBrowserChom.OleObject.Document.Links.Item(i-1).href;

jesli linkow w webbrowser jest 160 ale sa indeksowane od 0 to ostatni link bedzie mial indeks 159. i jak bedziesz chcial odczytac link nr 160 to wywali blad bo takeigo nie bedzie.

0

Aha, zmieniłem indeksowanie tablicy i zrobiłem taką pętlę:
for i := 0 to WebBrowserChom.OleObject.Document.Links.Length - 1 do
Teraz będzie już działać :)

0

Nie wiem po co ta tablica (bo przecież masz linki w RichEdit) ale jak już potrzebujesz tej tablicy to tak:

var
  Link: array of string;
  i, count: Integer;
begin
  if not Assigned(WebBrowser1.Document) then exit; //to była prawdopodobnie przyczyna błędu
  count:= WebBrowser1.OleObject.Document.Links.Length - 1;
  SetLength(Link, count); //od razu po co wiele razy w pętli
  for i:= 0 to count do
  begin
    Link[i] := WebBrowser1.OleObject.Document.Links.Item(i).Href;
    RichEdit1.Lines.Add(Link[i])
  end;
end;
0

W pętli odwołujesz się po tablicy w ten sposób

for i := High(Lista) downto Low(Lista)

//ewentualnie jeśli ważna jest kolejność
for i := Low(Lista) to High(Lista) do
0

Już mi działa z tym, tylko jest kolejny problem, po pobraniu linków mam coś takiego, że mam najpierw kilka linków różnych, a potem jeden link powtarza się 2 razy:
link1
link2
link3
link4
link4
link5
link5
link6
link6
Chcę żeby mi te dublety usuwało, wystukałem takie cuś:

for i2 := ListBoxLinki.Count-1 downto 0 do
  begin
    if ListBoxLinki.Items[i2] = ListBoxLinki.Items[i2 - 1] then
    ListBoxLinki.Items.Delete(i2 - 1);
  end;

Tylko mi wywala błąd EStringListError 'List index Out of bounds(153)' Co zrobić żeby tego błędu nie było?

0

zrob inaczej: przed dodaniem sprawdzaj czy juz takiego nie ma w listboxie:

  if ListBoxLinki.Items.IndexOf(link)<0
    then ListBoxLinki.Items.Add(link);

a co do samego bledu: jak usuniesz item z listboxa to zmieni sie ilosc itemow a petla jest od tej ilosci zalezna (for i2 := ListBoxLinki.Count-1).
jesli juz to w takich przypadkach uzywa sie petli while..do lub repeat..until

//btw temat dosc prosty wiec nie wiem czy nie do Newbie.

0

A jak już chcesz się bawić usuwanie później to tak:

var
  i, index: Integer;
begin
  for i:=ListBox1.Items.Count -1 downto 0 do
  begin
    index:= ListBox1.Items.IndexOf(ListBox1.Items.Strings[i]);
    if (index > -1) and (index <> i) then
      ListBox1.Items.Delete(i);
  end;
end;
0

Wielkie dzięki koledzy! :) Już działa! :)
PS. Dawno tutaj nie wchodziłem, niech oczywiście modzi do newbie przenoszą ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1