ProjectManagerDm.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. unit ProjectManagerDm;
  2. interface
  3. uses
  4. TenderBackupManager,
  5. SysUtils, Classes, DB, DBClient, Provider, ADODB, Connections, ZhAPI,
  6. sdDB, sdProvider, sdIDTree;
  7. type
  8. TProjectManagerData = class(TDataModule)
  9. sdpProjectsInfo: TsdADOProvider;
  10. sddProjectsInfo: TsdDataSet;
  11. sdvProjectsInfo: TsdDataView;
  12. sdpTenderProperty: TsdADOProvider;
  13. sddTenderProperty: TsdDataSet;
  14. sdvTenderProperty: TsdDataView;
  15. sdvProjectsSpare: TsdDataView;
  16. procedure sdvProjectsInfoGetText(var Text: String;
  17. ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
  18. DisplayText: Boolean);
  19. procedure sdvProjectsInfoFilterRecord(ARecord: TsdDataRecord;
  20. var Allow: Boolean);
  21. procedure DataModuleCreate(Sender: TObject);
  22. procedure sdvProjectsInfoBeforeDeleteRecord(ARecord: TsdDataRecord;
  23. var Allow: Boolean);
  24. private
  25. FConnection: TEncryptConnection;
  26. FProjectsTree: TsdIDTree;
  27. FBackupManager: TBackupManager;
  28. procedure UpdateManagerDataBase;
  29. //procedure ReNameCurrentProject(const AName: string);
  30. procedure CreateNewProjectFile(const AName: string);
  31. procedure DeleteAllTenderFiles(ANode: TsdIDTreeNode);
  32. procedure DeleteAttachmentFiles(ANode: TsdIDTreeNode);
  33. function CreateBackupFolder(AProjectID: Integer): string;
  34. procedure ExportTender(ARec: TsdDataRecord; AFileName: string);
  35. function NewID: Integer;
  36. public
  37. constructor Create;
  38. destructor Destroy; override;
  39. procedure Open;
  40. procedure Save;
  41. function HasProject: Boolean;
  42. function ExistProject(const AName: string; ANode: TsdIDTreeNode): Boolean;
  43. function ProjectID(const AName: string; ANode: TsdIDTreeNode): Integer;
  44. // 云版要记下网络文件夹的ID和层次。
  45. function InsertProject(const AName: string; APreNode: TsdIDTreeNode; AFolderID: Integer = -1; AFolderLevel: Integer = -1): TsdIDTreeNode;
  46. function InsertSubProject(const AName: string; AParent: TsdIDTreeNode; AFolderID: Integer = -1; AFolderLevel: Integer = -1): TsdIDTreeNode;
  47. function InsertTender(const AName: string; AParent: TsdIDTreeNode): TsdIDTreeNode;
  48. procedure Delete;
  49. procedure ReName(const AName: string; ANode: TsdIDTreeNode);
  50. procedure RestoreTender(AID: Integer);
  51. procedure RefreshSeedID;
  52. function BackupPath(AProjectID: Integer): String;
  53. procedure AddOpenTenderBackup(AProjectID: Integer);
  54. procedure AddSaveTenderBackup(AProjectID: Integer);
  55. property ProjectsTree: TsdIDTree read FProjectsTree;
  56. end;
  57. implementation
  58. uses
  59. UtilMethods, UpdateDataBase, ProjectCommands, PHPWebDm, ConstUnit;
  60. {$R *.dfm}
  61. { TProjectManagerData }
  62. constructor TProjectManagerData.Create;
  63. begin
  64. inherited Create(nil);
  65. FConnection := TEncryptConnection.Create;
  66. FProjectsTree := TsdIDTree.Create;
  67. FProjectsTree.KeyFieldName := 'ID';
  68. FProjectsTree.ParentFieldName := 'ParentID';
  69. FProjectsTree.NextSiblingFieldName := 'NextSiblingID';
  70. FProjectsTree.AutoCreateKeyID := True;
  71. FProjectsTree.AutoExpand := True;
  72. FProjectsTree.SeedID := 1;
  73. FProjectsTree.DataView := sdvProjectsInfo;
  74. FBackupManager := TBackupManager.Create;
  75. end;
  76. procedure TProjectManagerData.CreateNewProjectFile(const AName: string);
  77. var
  78. TempFolder: string;
  79. begin
  80. try
  81. TempFolder := GenerateTempFolder(GetTempFilePath);
  82. CopyFileOrFolder(GetEmptyDataBaseFileName, TempFolder + '\Main.dat');
  83. ZipFolder(TempFolder, GetMyProjectsFilePath + AName);
  84. finally
  85. DeleteFileOrFolder(TempFolder);
  86. end;
  87. end;
  88. procedure TProjectManagerData.Delete;
  89. begin
  90. if HasProject then
  91. begin
  92. DeleteAttachmentFiles(FProjectsTree.Selected);
  93. DeleteAllTenderFiles(FProjectsTree.Selected);
  94. FProjectsTree.DeleteNode(FProjectsTree.Selected);
  95. Save;
  96. end;
  97. end;
  98. destructor TProjectManagerData.Destroy;
  99. begin
  100. FBackupManager.Free;
  101. FProjectsTree.Free;
  102. FConnection.Free;
  103. inherited;
  104. end;
  105. function TProjectManagerData.ExistProject(const AName: string;
  106. ANode: TsdIDTreeNode): Boolean;
  107. var
  108. vCur: TsdIDTreeNode;
  109. begin
  110. Result := False;
  111. if not Assigned(ANode) then Exit;
  112. vCur := ANode.FirstChild;
  113. while not Result and Assigned(vCur) do
  114. begin
  115. Result := vCur.Rec.ValueByName('Name').AsString = AName;
  116. vCur := vCur.NextSibling;
  117. end;
  118. end;
  119. function TProjectManagerData.HasProject: Boolean;
  120. begin
  121. Result := sddProjectsInfo.RecordCount > 0;
  122. end;
  123. function TProjectManagerData.InsertProject(const AName: string;
  124. APreNode: TsdIDTreeNode; AFolderID: Integer; AFolderLevel: Integer): TsdIDTreeNode;
  125. var
  126. vNew: TsdIDTreeNode;
  127. bOnLine, bCanCreate: Boolean;
  128. begin
  129. // 云版判断是否已存在的标准是服务端传来的ID,不是单机版所使用的名称。
  130. // 判断条件写在这里面不合适,因为云版调用不正确,应该写到方法外面。
  131. // 现在已经这样了,改起来麻烦,先补丁的方式用着。
  132. if G_IsCloud then
  133. bCanCreate := True
  134. else if (not G_IsCloud) and (not Assigned(APreNode)
  135. or not ExistProject(AName, APreNode.Parent)) then
  136. bCanCreate := True
  137. else
  138. bCanCreate := False;
  139. if bCanCreate then
  140. begin
  141. RefreshSeedID;
  142. if Assigned(APreNode) then
  143. vNew := FProjectsTree.Add(APreNode.ParentID, APreNode.NextSiblingID)
  144. else
  145. vNew := FProjectsTree.Add(-1, -1);
  146. vNew.Rec.BeginUpdate;
  147. vNew.Rec.ValueByName('Type').AsInteger := 0;
  148. vNew.Rec.ValueByName('Name').AsString := AName;
  149. {---------------------------------------------------------------------------
  150. 恼火的问题:直接写成下面这样,则第二句编译不进:
  151. if G_IsOnLine then
  152. vNew.Rec.ValueByName('WebUserID').AsInteger := PHPWeb.UserID;
  153. 这里用局部变量bOnLine转接一下,能解决问题。
  154. ---------------------------------------------------------------------------}
  155. bOnLine := G_IsCloud;
  156. if bOnLine then
  157. begin
  158. vNew.Rec.ValueByName('WebID').AsInteger := AFolderID;
  159. vNew.Rec.ValueByName('WebUserID').AsInteger := PHPWeb.UserID;
  160. vNew.Rec.ValueByName('WebFolderLevel').AsInteger := AFolderLevel;
  161. end;
  162. vNew.Rec.EndUpdate;
  163. Result := vNew;
  164. Save;
  165. end
  166. else
  167. raise Exception.Create('存在同名类别!');
  168. end;
  169. function TProjectManagerData.InsertSubProject(const AName: string;
  170. AParent: TsdIDTreeNode; AFolderID: Integer; AFolderLevel: Integer): TsdIDTreeNode;
  171. var
  172. vNew: TsdIDTreeNode;
  173. bOnLine, bCanCreate: Boolean;
  174. begin
  175. if G_IsCloud then
  176. bCanCreate := True
  177. else if (not G_IsCloud) and (not ExistProject(AName, AParent)) then
  178. bCanCreate := True
  179. else
  180. bCanCreate := False;
  181. if bCanCreate then
  182. begin
  183. RefreshSeedID;
  184. vNew := FProjectsTree.Add(AParent.ID, -1);
  185. vNew.Rec.ValueByName('Type').AsInteger := 0;
  186. vNew.Rec.ValueByName('Name').AsString := AName;
  187. {---------------------------------------------------------------------------
  188. 恼火的问题:直接写成下面这样,则第二句编译不进:
  189. if G_IsOnLine then
  190. vNew.Rec.ValueByName('WebUserID').AsInteger := PHPWeb.UserID;
  191. 这里用局部变量bOnLine转接一下,能解决问题。
  192. ---------------------------------------------------------------------------}
  193. bOnLine := G_IsCloud;
  194. if bOnLine then
  195. begin
  196. vNew.Rec.ValueByName('WebID').AsInteger := AFolderID;
  197. vNew.Rec.ValueByName('WebUserID').AsInteger := PHPWeb.UserID;
  198. vNew.Rec.ValueByName('WebFolderLevel').AsInteger := AFolderLevel;
  199. end;
  200. Result := vNew;
  201. Save;
  202. end
  203. else
  204. raise Exception.Create('存在同名类别!');
  205. end;
  206. function TProjectManagerData.InsertTender(const AName: string;
  207. AParent: TsdIDTreeNode): TsdIDTreeNode;
  208. var bOnLine: Boolean;
  209. begin
  210. if not ExistProject(AName, AParent) then
  211. begin
  212. RefreshSeedID;
  213. Result := FProjectsTree.Add(AParent.ID, -1);
  214. {---------------------------------------------------------------------------
  215. 恼火的问题:直接写成下面这样,则第二句编译不进:
  216. if G_IsOnLine then
  217. Result.Rec.ValueByName('WebUserID').AsInteger := PHPWeb.UserID;
  218. 这里用局部变量bOnLine转接一下,能解决问题。
  219. ---------------------------------------------------------------------------}
  220. // if G_IsOnLine then
  221. // Result.Rec.ValueByName('WebUserID').AsInteger := PHPWeb.UserID; // 编译不进
  222. bOnLine := G_IsCloud;
  223. if bOnLine then
  224. Result.Rec.ValueByName('WebUserID').AsInteger := PHPWeb.UserID;
  225. Result.Rec.ValueByName('Type').AsInteger := 1;
  226. Result.Rec.ValueByName('Name').AsString := AName;
  227. Result.Rec.ValueByName('PhaseCount').AsInteger := 0;
  228. Result.Rec.ValueByName('AuditStatus').AsInteger := 0;
  229. Result.Rec.ValueByName('FileName').AsString :=
  230. ExtractSimpleFileName(GetNewGUIDFileName(GetMyProjectsFilePath));
  231. Result.Rec.ValueByName('CreateDate').AsString := FormatDateTime('yyyy-mm-dd', Date);
  232. CreateNewProjectFile(Result.Rec.ValueByName('FileName').AsString);
  233. Save;
  234. end
  235. else
  236. raise Exception.Create('存在同名标段!');
  237. end;
  238. procedure TProjectManagerData.Open;
  239. var
  240. FQuery: TADOQuery;
  241. begin
  242. FConnection.Open(GetAppFilePath + 'Data\ProjectManager.dat');
  243. UpdateManagerDataBase;
  244. sdpProjectsInfo.Connection := FConnection.Connection;
  245. sddProjectsInfo.Open;
  246. sdvProjectsInfo.Open;
  247. sdvProjectsSpare.Open;
  248. sddProjectsInfo.AddIndex('idxID', 'ID');
  249. sdvProjectsInfo.IndexName := 'idxID';
  250. sdpTenderProperty.Connection := FConnection.Connection;
  251. sddTenderProperty.Open;
  252. sdvTenderProperty.Open;
  253. end;
  254. procedure TProjectManagerData.Save;
  255. begin
  256. sddTenderProperty.Save;
  257. sddProjectsInfo.Save;
  258. FConnection.Save;
  259. end;
  260. procedure TProjectManagerData.UpdateManagerDataBase;
  261. var
  262. vUpdator: TUpdateManagerDB;
  263. begin
  264. vUpdator := TUpdateManagerDB.Create;
  265. try
  266. vUpdator.Update(FConnection);
  267. finally
  268. vUpdator.Free;
  269. end;
  270. end;
  271. procedure TProjectManagerData.sdvProjectsInfoGetText(var Text: String;
  272. ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
  273. DisplayText: Boolean);
  274. function NumToAuditStatus(AValue: Integer): string;
  275. begin
  276. case AValue of
  277. -1:
  278. if ARecord.ValueByName('PhaseCount').AsInteger = 0 then
  279. Result := '原报'
  280. else
  281. Result := '批复';
  282. 0:
  283. Result := '原报';
  284. else
  285. Result := Format('%d 审', [AValue]);
  286. end;
  287. end;
  288. begin
  289. if not Assigned(ARecord) then Exit;
  290. if SameText(AColumn.FieldName, 'AuditStatus') then
  291. if ARecord.ValueByName('Type').AsInteger = 1 then
  292. Text := NumToAuditStatus(AValue.AsInteger)
  293. else
  294. Text := '';
  295. end;
  296. procedure TProjectManagerData.DeleteAllTenderFiles(ANode: TsdIDTreeNode);
  297. var
  298. iChild: Integer;
  299. begin
  300. if ANode.HasChildren then
  301. for iChild := 0 to ANode.ChildCount - 1 do
  302. DeleteAllTenderFiles(ANode.ChildNodes[iChild])
  303. else if ANode.Rec.ValueByName('Type').AsInteger = 1 then
  304. DeleteFile(GetMyProjectsFilePath + ANode.Rec.ValueByName('FileName').AsString);
  305. end;
  306. procedure TProjectManagerData.ReName(const AName: string;
  307. ANode: TsdIDTreeNode);
  308. begin
  309. ANode.Rec.ValueByName('Name').AsString := AName;
  310. Save;
  311. end;
  312. procedure TProjectManagerData.RestoreTender(AID: Integer);
  313. var
  314. vNode: TsdIDTreeNode;
  315. sRestoreFile: string;
  316. Exportor: TTenderExport;
  317. begin
  318. vNode := FProjectsTree.FindNode(AID);
  319. if not FileExists(GetMyProjectsFilePath + vNode.Rec.ValueByName('FileName').AsString) then Exit;
  320. sRestoreFile := GetBackUpFilePath + vNode.Rec.ValueByName('Name').AsString
  321. + '[' + FormatDateTime('yyyy-mm-dd hh,nn,ss', Now) + '].mtf';
  322. Exportor := TTenderExport.Create(vNode.Rec, sRestoreFile);
  323. try
  324. Exportor.Execute;
  325. finally
  326. Exportor.Free;
  327. end;
  328. end;
  329. procedure TProjectManagerData.sdvProjectsInfoFilterRecord(
  330. ARecord: TsdDataRecord; var Allow: Boolean);
  331. begin
  332. if G_IsCloud then
  333. begin
  334. if ARecord.ValueByName('WebUserID').AsInteger = PHPWeb.UserID then
  335. Allow := True
  336. else
  337. Allow := False;
  338. end
  339. else
  340. begin
  341. if ARecord.ValueByName('WebUserID').AsInteger = 0 then
  342. Allow := True
  343. else
  344. Allow := False;
  345. end;
  346. end;
  347. procedure TProjectManagerData.DataModuleCreate(Sender: TObject);
  348. begin
  349. // 单机版也要过滤:防止单机版程序能显示所有用户的项目。
  350. // if G_IsOnLine then
  351. sdvProjectsInfo.Filtered := True;
  352. sdvProjectsSpare.Filtered := True;
  353. end;
  354. function TProjectManagerData.NewID: Integer;
  355. var
  356. idxID: TsdIndex;
  357. begin
  358. idxID := sddProjectsInfo.FindIndex('idxID');
  359. Result := idxID.Records[idxID.RecordCount - 1].ValueByName('ID').AsInteger + 1;
  360. end;
  361. procedure TProjectManagerData.RefreshSeedID;
  362. begin
  363. FProjectsTree.SeedID := NewID;
  364. end;
  365. function TProjectManagerData.BackupPath(AProjectID: Integer): String;
  366. var
  367. Rec: TsdDataRecord;
  368. begin
  369. Result := GetAppFilePath + 'FileBackup\TenderBackup';
  370. Rec := ProjectsTree.FindNode(AProjectID).Rec;
  371. if Rec.ValueByName('BackupFolder').AsString = '' then
  372. Rec.ValueByName('BackupFolder').AsString := CreateBackupFolder(AProjectID);
  373. Result := Result + '\' + Rec.ValueByName('BackupFolder').AsString + '\';
  374. end;
  375. function TProjectManagerData.CreateBackupFolder(
  376. AProjectID: Integer): string;
  377. function GetParentNames(ANode: TsdIDTreeNode): string;
  378. var
  379. stnParent: TsdIDTreeNode;
  380. begin
  381. Result := '';
  382. stnParent := ANode.Parent;
  383. while Assigned(stnParent) do
  384. begin
  385. if Result <> '' then
  386. Result := stnParent.Rec.ValueByName('Name').AsString + '--' + Result
  387. else
  388. Result := stnParent.Rec.ValueByName('Name').AsString;
  389. stnParent := stnParent.Parent;
  390. end;
  391. end;
  392. var
  393. stnNode: TsdIDTreeNode;
  394. sGUID, sPath: string;
  395. sgs: TStringList;
  396. begin
  397. stnNode := ProjectsTree.FindNode(AProjectID);
  398. Result := stnNode.Rec.ValueByName('BackupFolder').AsString;
  399. if Result <> '' then Exit;
  400. sPath := GetAppFilePath + 'FileBackup\TenderBackup\';
  401. sGUID := GetNewGUIDFileName(sPath);
  402. if FileExists(sGUID) then DeleteFile(sGUID);
  403. CreateDirectoryInDeep(sGUID);
  404. sgs := TStringList.Create;
  405. try
  406. sgs.Add('项目备份文件夹');
  407. sgs.Add(Format('项目名称:%s', [stnNode.Rec.ValueByName('Name').AsString]));
  408. sgs.Add(Format('所属项目:%s', [GetParentNames(stnNode)]));
  409. sgs.Add(Format('创建时间:%s', [DateTimeToStr(Now)]));
  410. finally
  411. sgs.SaveToFile(sGUID + '\说明.txt');
  412. sgs.Free;
  413. end;
  414. Result := ExtractSimpleFileName(sGUID)
  415. end;
  416. procedure TProjectManagerData.sdvProjectsInfoBeforeDeleteRecord(
  417. ARecord: TsdDataRecord; var Allow: Boolean);
  418. var
  419. sOrgFolder, sNewFolder: string;
  420. begin
  421. if ARecord.ValueByName('BackupFolder').AsString <> '' then
  422. begin
  423. sOrgFolder := GetAppFilePath + 'FileBackup\TenderBackup\'
  424. + ARecord.ValueByName('BackupFolder').AsString;
  425. sNewFolder := GetAppFilePath + 'FileBackup\RecycleBackup\'
  426. + ARecord.ValueByName('BackupFolder').AsString;
  427. CopyFileOrFolder(sOrgFolder, sNewFolder);
  428. DeleteFileOrFolder(sOrgFolder);
  429. end;
  430. end;
  431. procedure TProjectManagerData.AddOpenTenderBackup(AProjectID: Integer);
  432. var
  433. BackupRec, Rec: TsdDataRecord;
  434. sBackupFile: string;
  435. begin
  436. Rec := sddProjectsInfo.FindKey('idxID', AProjectID);
  437. if not Assigned(Rec) then Exit;
  438. FBackupManager.LoadBackupFile(BackupPath(AProjectID));
  439. if FBackupManager.LastestOpenBackupIsToday then Exit;
  440. sBackupFile := FBackupManager.OpenBackupFile;
  441. if FileExists(sBackupFile) then DeleteFile(sBackupFile);
  442. ExportTender(Rec, sBackupFile);
  443. end;
  444. procedure TProjectManagerData.AddSaveTenderBackup(AProjectID: Integer);
  445. var
  446. BackupRec, Rec: TsdDataRecord;
  447. sBackupFile: string;
  448. begin
  449. Rec := sddProjectsInfo.FindKey('idxID', AProjectID);
  450. if not Assigned(Rec) then Exit;
  451. FBackupManager.LoadBackupFile(BackupPath(AProjectID));
  452. sBackupFile := FBackupManager.SaveBackupFile;
  453. if FileExists(sBackupFile) then DeleteFile(sBackupFile);
  454. ExportTender(Rec, sBackupFile);
  455. end;
  456. procedure TProjectManagerData.ExportTender(ARec: TsdDataRecord;
  457. AFileName: string);
  458. var
  459. Exportor : TTenderExport;
  460. begin
  461. Exportor := TTenderExport.Create(ARec, AFileName);
  462. try
  463. Exportor.Execute;
  464. finally
  465. Exportor.Free;
  466. end;
  467. end;
  468. function TProjectManagerData.ProjectID(const AName: string;
  469. ANode: TsdIDTreeNode): Integer;
  470. var
  471. vCur: TsdIDTreeNode;
  472. begin
  473. Result := -1;
  474. if not Assigned(ANode) then Exit;
  475. vCur := ANode.FirstChild;
  476. while (Result = -1) and Assigned(vCur) do
  477. begin
  478. if vCur.Rec.ValueByName('Name').AsString = AName then
  479. Result := vCur.ID;
  480. vCur := vCur.NextSibling;
  481. end;
  482. end;
  483. procedure TProjectManagerData.DeleteAttachmentFiles(ANode: TsdIDTreeNode);
  484. var sDir: string;
  485. procedure DeleteAtch(ANode: TsdIDTreeNode);
  486. begin
  487. // 如果文件名为空,删除时会删除整个附件文件夹,危险!
  488. if ANode.Rec.ValueByName('FileName').AsString = '' then Exit;
  489. sDir := GetMyProjectsFilePath + 'Attachment\' + ANode.Rec.ValueByName('FileName').AsString;
  490. DeleteFolder(sDir);
  491. end;
  492. procedure DeleteNodes(ANode: TsdIDTreeNode);
  493. begin
  494. if ANode = nil then Exit;
  495. if ANode.FirstChild <> nil then
  496. DeleteNodes(ANode.FirstChild);
  497. if ANode.Rec.ValueByName('Type').AsInteger = 1 then
  498. DeleteAtch(ANode);
  499. if ANode.NextSibling <> nil then
  500. DeleteNodes(ANode.NextSibling);
  501. end;
  502. begin
  503. if not G_IsCloud then
  504. begin
  505. if not Assigned(ANode) then Exit;
  506. if ANode.Rec.ValueByName('Type').AsInteger = 0 then
  507. begin
  508. if Assigned(ANode.FirstChild) then
  509. DeleteNodes(ANode.FirstChild);
  510. end
  511. else
  512. DeleteAtch(ANode);
  513. end;
  514. end;
  515. end.