Архивация в Dynamics NAV средствами Windows

Вы когда-нибудь обращали внимание на то, что проводник Windows может показывать содержимое Zip архива? К тому же Вы можете добавлять в архив файлы и извлекать их. Как-то я задался вопросом: как можно использовать эту возможность из Navision? Ведь в этом случае мне не придется заботиться о том, чтобы устанавливать архиватор на каждой машине.  Давайте разберемся с этим вопросом.
Все приведенные процедуры являются рабочими, но в них убраны дополнительные проверки для демонстрации принципов использования архивирования/разархивирования.

Добавление файла в архив

ZIP_ДобавитьФайл(ZipFile : Text[250];AddFile : Text[250]) result : Boolean
//***********************************
// Добавить файл в zip архив
//  параметры
//     ZipFile  - имя zip архива
//     AddFile  - имя добавляемого файла
//  возврат
//     result - True если операция прошла успешно
//****************************
//Локальные переменные
//  oShellApp   Automation  'Microsoft Shell Controls And Automation'.Shell
//  fld Automation  'Microsoft Shell Controls And Automation'.Folder   
//  FileCount   Integer    
//  SleepCount  Integer    
//***********************************

result:=FALSE;
CREATE(oShellApp);
fld:=oShellApp.NameSpace(ZipFile);
SleepCount:=0;
FileCount:=fld.Items.Count;
SLEEP(50);
fld.CopyHere(AddFile); //только запускается архивирование
//теперь проверяем чтобы архивация закончилась
//кол-во файлов должно стать +1
SLEEP(50);
WHILE (fld.Items.Count<FileCount+1) AND (SleepCount<1000) DO
BEGIN
  SLEEP(50);
  SleepCount+=1;
END;
IF fld.Items.Count=FileCount+1 THEN result:=TRUE;
CLEAR(fld);
CLEAR(oShellApp);
SLEEP(50);

////////////////////////////////////

С точки зрения оболочки Zip файл это папка. Поэтому для архивации нам необходимо вызвать oShellApp.NameSpace(ZipFile) который возвращает объект Folder, с помощью которого можно получить доступ к содержимому архива. Для того, чтобы система правильно поняла, что это архив,  убедитесь что расширение файла “zip”.

Непосредственно архивирование начинается при вызове функции fld.CopyHere(AddFile). Архивирование ведется в отдельном потоке и поэтому нам необходимо, каким-то образом понять, что архивирование закончилось. Для этого перед началом архивирования сохраняется количество файлов в папке в переменной FileCount и запускается цикл проверки количества файлов в папке.  С помощью переменной SleepCont и процедуры SLEEP регулируется длительность ожидания.

Полученная функция позволяет только добавлять файлы в архив. Если нужно создать новый Zip файл, то нужно немного пошаманить, т.к. даже пустой архив должен иметь определенную структуру. Ниже приведена функция, которая создает такой пустой файл.

ZIP_Создать(ZipFile : Text[250])
//***********************************
// Создать пустой файл zip архива
//  параметры
//     ZipFile  - имя zip файла
//****************************
//Локальные переменные
//  ch1 Char       
//  i   Integer    
//  f   File       
//***********************************
f.CREATE(ZipFile);
ch1:=80; //'P'
f.WRITE(ch1);
ch1:=75; //'K'
f.WRITE(ch1);
ch1:=5;
f.WRITE(ch1);
ch1:=6;
f.WRITE(ch1);
FOR i:=1 TO 18 DO
BEGIN
  ch1:=0;
  f.WRITE(ch1);
END;
f.CLOSE;

////////////////////////////////////

Теперь можно написать функцию, которая архивирует файл в архив с тем же именем и расширением “zip”.

ZIP_ЗаархивироватьОдинФайл(File : Text[250]) zipFile : Text[250]
//***********************************
// Создать zip архив и добавить туда файл.
// Имя zip архива - это имя добовляемого файла
//  параметры
//     File  - имя архивируемого файла
//  возврат
//     zipFile - имя zip архива
//****************************
//Локальные переменные
//  i   Integer    
//  dot_pos Integer    
//***********************************

//поиск расширения
dot_pos:=0;
FOR i:=STRLEN(File) DOWNTO 1 DO
  IF File[i]='.' THEN dot_pos:=i;

zipFile:=COPYSTR(File,1,dot_pos)+'zip';

ZIP_Создать(zipFile);
ZIP_ДобавитьФайл(zipFile,File);

////////////////////////////////////

Как видите все уже достаточно просто.

Теперь нужно разобраться с добавлением большого количества файлов в архив.

ZIP_ЗаархивироватьФайлы(ZipFile : Text[250];VAR СписокФайлов : Record "Коды Резервов")
//***********************************
// Создать zip архив и добавить туда файлы из списка файлов
//  параметры
//     ZipFile  - имя zip архива
//     СписокФайлов - временая таблица со списком передаваемых файлов. "СписокФайлов.Описание" - полный путь и имя файла
//****************************

ZIP_Создать(ZipFile);
IF СписокФайлов.FINDSET THEN
BEGIN
REPEAT
  IF (СписокФайлов.Описание<>'') and Exists(СписокФайлов.Описание)
  THEN ZIP_ДобавитьФайл(ZipFile,СписокФайлов.Описание);
UNTIL СписокФайлов.NEXT=0;
END;

////////////////////////////////////

Последний шаг — извлечение файлов из архива.

ZIP_РазархивироватьВПапку(ZipFile : Text[250];ExtractFolder : Text[250])
//***********************************
// Разархивировать zip файл в папку
//  параметры
//     ZipFile  - архив
//     ExtractFolder - папка в которую будут помещены файлы из архива
//****************************
//Локальные переменные
//  oShellApp   Automation  'Microsoft Shell Controls And Automation'.Shell
//  fldZip  Automation  'Microsoft Shell Controls And Automation'.Folder   
//  fldExtr Automation  'Microsoft Shell Controls And Automation'.Folder   
//  FileCount   Integer    
//  SleepCount  Integer    
//***********************************

CREATE(oShellApp);
fldZip:=oShellApp.NameSpace(ZipFile);
fldExtr:=oShellApp.NameSpace(ExtractFolder);
//запуск разархивирования
fldExtr.CopyHere(fldZip.Items);

//дожидаемся пока количество файлов в папке разархивирования
//не станет равно количеству файлов в архиве
//или таймаут не истечет
SleepCount:=0;
WHILE (fldExtr.Items.Count<fldZip.Items.Count) AND (SleepCount<1000) DO
BEGIN
  SLEEP(50);
  SleepCount+=1;
END;
CLEAR(oShellApp);

////////////////////////////////////

Процесс разархивирования очень похож на добавление файлов в архив, поэтому я не буду подробно рассказывать, как это делается. Отдельно необходимо отметить, что папка,  в которую будет проведено разархивирование, должна быть пустой, т.к. проверка завершения архивирования основывается на количестве файлов в архиве и конечной папке.

Теперь у Вас есть небольшая библиотека функций с помощью, которой Вы сможете выполнять простейшие функции над архивами. Моя практика показывает, что эти функции работают на всех версиях Windows, начиная с XP.

Автор:

Количество статей, опубликованных автором: 5. Дополнительная информация об авторе появится вскоре.

Добавить комментарий