|
|
#1 |
|
Участник
|
Здравствуйте!
У меня есть проблема, которая поставила меня в тупик. Я сделал XMLPort для NAV 2013, который импортирует Заказы продажи. Есть папки в NAS: в одной содержатся XML файлы (1ая папка), в другую нужно перекидывать их (2ая папка). Я сделал на странице Список продаж кнопку, при нажатии на которую просматривается 1ая папка, запускается XMLPort для каждого XML файла в ней, далее файл попадает во 2ую папку. Все работает. Проблема в том, что мне нужно, чтобы NAV самостоятельно делал данные действия с определенной заданной периодичностью без действий со стороны пользователя. Сейчас же пользователь должен регулярно нажимать на кнопку. При этом, выскакивает окно для каждого файла (не то, на котором выбор направления и фильтры - его я убрал. То окно, на котором выбор файла. Его я убрать не могу). Пользователь в этом окне нажимает только кнопку ОК (все уже выбрано и вбито за него). Если файлов 10, то окон выскакивает тоже 10, а пользователь должен лишние 10 раз нажать интер, что не очень хорошо. Есть какие-либо идеи? Код триггера OnAction кнопки на странице: Код: SalesSet.GET;
DirectoryInfo := DirectoryInfo.DirectoryInfo(SalesSet."Orders from Customers");
List := DirectoryInfo.GetFiles('*.XML');
enumerator := List.GetEnumerator;
WHILE enumerator.MoveNext DO
BEGIN
FileInfo := enumerator.Current;
xmlPortUploadOrder.FILENAME(SalesSet."Orders from Customers" + FileInfo.Name);
xmlPortUploadOrder.RUN;
CLEAR(xmlPortUploadOrder);
FileInfo.CopyTo(SalesSet."Archive Orders from Customers" + FileInfo.Name, TRUE);
FileInfo.Delete;
END;Используемые переменные: Name DataType Subtype DirectoryInfo DotNet System.IO.DirectoryInfo.'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' FileInfo DotNet System.IO.FileInfo.'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' List DotNet System.Collections.Generic.List`1.'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' enumerator DotNet System.Collections.IEnumerator.'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' SalesSet Record Sales & Receivables Setup xmlPortUploadOrder XMLport Orders From Web П.С.: получается, что у меня 2 задачи. Вот они, в порядке уменьшения приоритета: 1) делегировать системе запуск XMLPort и перемещение файлов; 2) убрать окно с выбором файла. |
|
|
|
|
#2 |
|
Участник
|
А использовать системную табличку File не пробовали? И для всего автоматизма настроить соответствующий Job Queue (T. 472) и повесить его выполнение на NAS?
Т.е. 1.создаёте один Codeunit для Job Queue. 2. В Codeunit'e проходитетe циклом по табличке File, находите там нужные вам XML-файлы, запускаете для каждого XML-Port (для этого процесса создать второй Codeunit) , в случае успеха/неудачи обработки каждого файла удаляете файл в папку ArchivOK или ArchivNOK. Т.е что-то типа: Код: fileRec.RESET;
fileRec.SETRANGE(Path, 'C:\');
IF fileRec.FINDFIRST THEN; // -> что-то типа нажатия клавиши F5 в Windows Explorer
fileRec.RESET;
fileRec.SETRANGE(Path, MyDirectory);
fileRec.SETRANGE("Is a file", TRUE);
fileRec.SETFILTER(Name, '*.xml);
IF fileRec.FINDSET THEN BEGIN
REPEAT
// обработка фаила вo втором Codeunit'e напр. по имени 'FileProcessing'
CLEAR(FileProcessing);
FileProcessing.SetFile(fileRec); // передача имени фаила в codeunit для обработки оного там хмл-портом
CLEARLASTERROR();
COMMIT;
IF FileProcessing.RUN() THEN BEGIN
RENAME(fileRec.Name,'C:\ArchivOK\fileRec.Name');
END ELSE BEGIN
RENAME(fileRec.Name,'C:\ArchivNOK\fileRec.Name');
// ... так же можно ещё Log написать типа файл такой то не обработан так => смотри GETLASTERRORTEXT
END;
UNTIL fileRec.NEXT = 0;
END; |
|
|
|
|
#3 |
|
Участник
|
Спасибо за совет, Алекс, он мне очень помог!
Автозапуск решил при помощи Job Queue, окно убрал запуская ХМЛ-порт через XMLPORT.IMPORT. Следующий код поместил в codeunit, который использовал в Job Queue: Код:
SalesSet.GET;
DirectoryInfo := DirectoryInfo.DirectoryInfo(SalesSet."Orders from Customers");
List := DirectoryInfo.GetFiles('*.XML');
enumerator := List.GetEnumerator;
WHILE enumerator.MoveNext DO
BEGIN
FileInfo := enumerator.Current;
XmlFile.OPEN(SalesSet."Orders from Customers" + FileInfo.Name);
XmlFile.CREATEINSTREAM(InputStream);
IF XMLPORT.IMPORT(XMLPORT::"Orders From Web", InputStream) THEN
BEGIN
FileInfo.CopyTo(SalesSet."Archive Orders from Customers" + FileInfo.Name, TRUE);
FileInfo.Delete;
END;
XmlFile.CLOSE;
END; |
|
|
|
|
#4 |
|
Участник
|
Не за что, если помог, то поставьте +1
/>Я всё-таки советую вынести обработку каждого файла из JobQueue-codeunit'а в отдельный codeunit и вызывать результат обработки посредством IF CODEUNIT.RUN() (т.е. как я уже описал). Как вы в этом новом codeunit'е эти файлы просматриваете / обрабатываете, вашим методом Dot.Net или File.таблицей, XML-Port'ом или ещё как: по барабану, главное: функциональность вынести в в отдельный codeunit и вызывать результат обработки КАЖДОГО файла посредством IF CODEUNIT.RUN(). В этом варианте программа обработает ВСЕ файлы, с положительным или отрицательным результатом, но ВСЕ. Поверьте моему опыту: в вашем варианте JobQueue примется например за обработку 100 файлов, на 15-ом файле случится какая-нибудь ошибка (XML-Port не сможет его прочитать /обработать или при импорте заказов в NAV-таблицы случилась ошибка при INSERT'е или VALIDATE (я надеюсь вы при импорте валидируете хотя бы самые важные поля!), и.т.д. и.т.п ), ваш JobQueue на этом 15-ом файле остановится и вылетит с соотв. ошибкой и остальные файлы останутся не обработанными. |
|
|
|
|
#5 |
|
Участник
|
Я, конечно, согласен, что так будет логичней, но конечное решение принимаю не я, а у клиента, как говорится, напряг с лицензией и диапазонами. Если все-таки решимся, обязательно так и сделаем)
По моему коду. Там ошибка. Я не могу удалять файл до его закрытия. Соответственно, он должен выглядеть так: Код: SalesSet.GET;
DirectoryInfo := DirectoryInfo.DirectoryInfo(SalesSet."Orders from Customers");
List := DirectoryInfo.GetFiles('*.XML');
enumerator := List.GetEnumerator;
WHILE enumerator.MoveNext DO
BEGIN
FileInfo := enumerator.Current;
XmlFile.OPEN(SalesSet."Orders from Customers" + FileInfo.Name);
XmlFile.CREATEINSTREAM(InputStream);
IF XMLPORT.IMPORT(XMLPORT::"Orders From Web", InputStream) THEN
BEGIN
FileInfo.CopyTo(SalesSet."Archive Orders from Customers" + FileInfo.Name, TRUE);
XmlFile.CLOSE;
FileInfo.Delete;
END
ELSE
XmlFile.CLOSE;
END; |
|
|