2011-11-22 3 views
2

좋아, 내가 할 수있는 모든 실수를 찾으려고 노력했지만 최선을 포기 했어. 도움이 필요해! 필자가 작성한 것은 내 직업을위한 대여를 관리하는 앱이며 날짜가 지나면 내 앱에서 2 개의 텍스트 파일에서 이름을 삭제합니다. 나는이 일을하기 위해 3 개의 작은 기능 (절차)을 썼다. 여기 :Delphi for 루프 및 StringList 오류

이 파일은 dates.dat 파일에서로드되고 직원 이름이있는 행은 제거됩니다.

procedure remDate(emp: String);/// Removes employee from date file 
var 
    pos1, i: integer; 
    dateList: TStringList; 
begin 
    dateList:=TStringList.Create; 
    dateList.LoadFromFile('Data\dates.dat'); 
    for i:=0 to dateList.Count-1 do begin 
    pos1:=AnsiPos(emp, dateList[i]); 
    if pos1<>0 then begin 
     dateList.Delete(i); 
     dateList.SaveToFile('Data\dates.dat'); 
    end; 
    end; 
    dateList.Free; 
end; //eo remDate 

이 항목은 perm.dat 파일에서 직원 이름이 포함 된 줄을 제거합니다.

procedure remPerm(emp: String);/// Removes employee from perm file 
var 
    pos1, i: integer; 
    permList: TStringList; 
begin 
    permList:=TStringList.Create; 
    permList.LoadFromFile('Data\perm.dat'); 
    for i:=0 to permList.Count-1 do begin 
    pos1:=AnsiPos(emp, permList[i]); 
    if pos1<>0 then begin 
     permList.Delete(i); 
     permList.SaveToFile('Data\perm.dat'); 
    end; 
    end; 
    permList.Free; 
end; //eo remPerm 

이 하나가 서로 붙습니다. isDue는 2 개의 날짜를 비교하고 날짜가 오늘이거나 과거 인 경우 TRUE를 반환하는 간단한 함수입니다. 그것은 updatePerms 절차에 remPerm을 얻을 때 내가 오류가

procedure updatePerms; 
var 
    empList: TStringList; 
    i: integer; 
begin 
    empList:=TStringList.Create; 
    empList.LoadFromFile('Data\employes.dat'); 
    for i:=0 to empList.Count-1 do begin 
    if isDue(empList[i]) then begin 
     remDate(empList[i]); 
     remPerm(empList[i]); (*) Here is where the error points. 
    end; 
    end; 
    empList.Free; 
end; 

. (*) 나는 바운드 (#)의 밖으로 EStringList 오류를 얻을. 직원의 기한이 오늘 일 때만 일어나는 많은 시도로 파악됩니다. 더 많은 정보가 필요하면 의견을 말하십시오! 미리 감사드립니다. 도움이 정말 감사합니다!

+0

아, btw 직원은 두 파일 중 한 번만 사용할 수 있습니다. – Gab

답변

18

문제는 for 루프를 사용하고 있다는 것입니다. for 루프의 끝점은 루프가 입력 될 때 한 번만 평가됩니다. 그 시점에서 100 개의 항목을 가질 수 있지만 일단 삭제를 시작하면 적은 항목이됩니다. 그러면 범위를 벗어나는 목록 색인 오류가 발생합니다. 직원이 한 번 이상이 발생하는 경우

procedure remDate(emp: String); 
/// Removes employee from date file 
var 
    pos1, i: integer; 
    dateList: TStringList; 
begin 
    dateList := TStringList.Create; 
    dateList.LoadFromFile('Data\dates.dat'); 
    for i := dateList.Count - 1 downto 0 do 
    begin 
    pos1 := AnsiPos(emp, dateList[i]); 
    if pos1 <> 0 then 
    begin 
     dateList.Delete(i); 
     dateList.SaveToFile('Data\dates.dat'); 
    end; 
    end; 
    dateList.Free; 
end; // eo remDate 

이 작동됩니다

간단한 수정은 for 루프를 반대하는 것입니다. 직원이 한 번 발생하면

그러나 초기 루프에서 종료 break를 사용할 수 있습니다

procedure remDate(emp: String); 
/// Removes employee from date file 
var 
    pos1, i: integer; 
    dateList: TStringList; 
begin 
    dateList := TStringList.Create; 
    dateList.LoadFromFile('Data\dates.dat'); 
    for i := 0 to dateList.Count - 1 do 
    begin 
    pos1 := AnsiPos(emp, dateList[i]); 
    if pos1 <> 0 then 
    begin 
     dateList.Delete(i); 
     dateList.SaveToFile('Data\dates.dat'); 
     Break; // <-- early exit 
    end; 
    end; 
    dateList.Free; 
end; // eo remDate 

또 다른 해결책은 while 루프를 사용하는 것입니다.

+0

정말 고마워요! 뿐만 아니라 당신은 나를 교정했지만 내 실수를 이해하게 만들었습니다! 그것이 그럴 수 있다고 생각했지만 멀리 보지 못했습니다. 나는 i = 0을 "downto"로 바꿨고 완전히 효과가있었습니다. 나는 또한 "휴식"이라고 언급했다. 나중에 참조 할 수 있도록! 다시 한 번 감사드립니다! – Gab

+0

목록 (문자열 목록, tlist)에서 항목을 삭제해야 할 때 항상 'while'루프를 사용했습니다. 이것을 위해'for..downto 0'을 사용하지 않을 생각입니다. 멋진 +1 –