Работа с файлами на стороне клиента
|
Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
Wazuuuuup Участник
Вступление в Клуб: 03.03.2014
|
Пн Мар 03, 2014 15:56  Работа с файлами на стороне клиента |
|
Полезность: Нет оценки
|
Всем здравствуйте!
Появилась необходимость создать механизм репликации файлов шаблонов отчетов на рабочие места пользователей.
Вкратце, суть сводится к справочнику с записями о каждом шаблоне на сервере с версией и проверке актуальности версии шаблона у клиента.
Смотрим версию шаблона в справочнике, смотрим версию у клиента в каталоге(допустим в тхт файлике список всех шаблонов и их версии), и в случае если у клиента шаблон устарел(или отсутствует), то заменяем(копируем) шаблон клиенту с сервера.
Столкнулся с проблемой, что функция stdio.open ни в какую не хочет открывать файлы на клиенте, только на сервере.
Знаю, что есть "Экспорт-импорт файлов" FILE$LOAD, который по идее должен решить мою проблему, но никак не могу разобраться как его применять..
Не могли бы вы подсказать как его использовать? Или какое-нибудь другое решение |
|
 |
dbmaslov Профи
Вступление в Клуб: 11.07.2007
|
Пн Мар 03, 2014 17:30   |
|
Полезность: Нет оценки
|
Добрый день, коллега!
Добро пожаловать в Клуб.
Разработка интересная. Вам поможет исследование операций работающих с файлами. Таких много. К сожалению сейчас нет под рукой словаря данных. Посмотрите через поиск в текстах операций словосочетание stdio.open.
У меня встречные вопросы:
1. как вы будете сверять файлы? не уверен, что используемый механизм в ЦФТ даст вам много информации о файле (максимум размер, а дату модификации скорее всего не получить).
2. не проще ли все шаблоны держать на централизованном сетевом диске и централизованно их обновлять? |
|
 |
Random Эксперт
Вступление в Клуб: 27.06.2011
|
Вт Мар 04, 2014 05:30  Re: Работа с файлами на стороне клиента |
|
Полезность: 1
|
Wazuuuuup пишет: | Всем здравствуйте!
Появилась необходимость создать механизм репликации файлов шаблонов отчетов на рабочие места пользователей.
Вкратце, суть сводится к справочнику с записями о каждом шаблоне на сервере с версией и проверке актуальности версии шаблона у клиента.
Смотрим версию шаблона в справочнике, смотрим версию у клиента в каталоге(допустим в тхт файлике список всех шаблонов и их версии), и в случае если у клиента шаблон устарел(или отсутствует), то заменяем(копируем) шаблон клиенту с сервера.
Столкнулся с проблемой, что функция stdio.open ни в какую не хочет открывать файлы на клиенте, только на сервере.
Знаю, что есть "Экспорт-импорт файлов" FILE$LOAD, который по идее должен решить мою проблему, но никак не могу разобраться как его применять..
Не могли бы вы подсказать как его использовать? Или какое-нибудь другое решение |
Прежде чем заниматься разработкой, необходимо вникнуть в парадигму клиент-сервер.
А для ТЯ2 - так и в парадигму трёхзвенной архитектуры. Но о ней в другой раз.
Итак, представьте себе двух друзей, одного назовём Клерк, и он выполняет инструкции, составленные на VBS, другого назовём СЕРВЕР, и он выполняет инструкции, составленные на PL+ (pl/sql).
Общаться они могут посредством телефона, это не очень медленно, но и не особенно быстро.
Сервер находится в помещении архива банка, с огромной картотекой. Он практически всемогущ. Однако, чтобы злые люди не заставили его выполнять злые дела, помещение архива банка закрыто на 70 замков, приставлена охрана, и просто так на улицу погулять не выйдешь.
Клерков много. Каждый Клерк находится в своём офисе и общается с миром через окошко приёма-выдачи документов. Подойдёт человек, поговорит, и уйдёт. И телефон ещё выключит.
Сервер сам обзванивать офисы не может.
И вот вы заставляете сервер сбегать в офис, оставить там документы? Первый же вопрос - а в какой? А если он закрыт? И т.д.
Или наоборот, сбегать в офис, забрать документы.
Максимум, вы можете дождаться, когда нужный клерк позвонит и спросит: а мои документы готовы? Тогда Сервер продиктует инструкции по телефону, клерк их выполнить и передаст клиенту.
Ну или наоборот, Клерк продиктует документы Серверу.
Делается это по определённому протоколу.
Последний раз редактировалось: Random (Вт Мар 04, 2014 05:49), всего редактировалось 1 раз |
|
 |
Random Эксперт
Вступление в Клуб: 27.06.2011
|
Вт Мар 04, 2014 05:44  Re: Работа с файлами на стороне клиента |
|
Полезность: 1
|
Итак, процессы сервер-клиент работают следующим образом:
1. на закладке доп.свойств есть рамка "Проверки". В ней два значения - "при загрузке операции" и "при смене элемента управления".
Проследите, чтобы были Клиент/Сервер.
2. если вы будете работать с элементом FILE$LOAD, вам придётся дожидаться обработки тела операции, потому что копирование файла произойдёт после нажатия кнопки OK, но до выполнения тела операции.
3. поэтому проще в секции валидации вызвать операцию, которая занимается копированием файлов. Например, DOCUMENT.COPYFILES. Поищите примеры, их много.
4. Это получается примерно так:
а) вы предлагаете пользователю выбрать файл.
б) вы предлагаете по окончании выбора нажать кнопку "принять".
в) по нажатии кнопки обрабатываете VB-событие OnClick, посылаете на сервер событие валидации с параметром - имя файла. Это событие отсылается немедленно, обрабатывается и управление возвращается только после его завершения.
г) на сервере вы получаете имя файла, заполняете нужные переменные, выполняете запуск операции копирования. Сразу предупреждаю, операция копирования должна выполниться в АРМ Навигатор, то есть на клиенте, а значит, вы можете только поджечь бикфордов шнур и всё. Когда вы вернёте управление в VB (выйдете из секции валидации), а затем выйдете и из события OnClick, только тогда АРМ Навигатор запустит операцию копирования файла.
д) после этого пользователь должен нажать ещё кнопку "Обработать принятый файл". Ну, тут уже файл будет на сервере, обрабатывайте.
А то ещё есть способы читать файлы из VB... |
|
 |
Random Эксперт
Вступление в Клуб: 27.06.2011
|
Вт Мар 04, 2014 06:04  Re: Работа с файлами на стороне клиента |
|
Полезность: Нет оценки
|
Wazuuuuup пишет: | Всем здравствуйте!
Появилась необходимость создать механизм репликации файлов шаблонов отчетов на рабочие места пользователей. |
Что касается самой задачи.
Вам не кажется, что обновлять шаблоны только для того, чтобы они были верной версии - это несколько бессмысленное занятие?
Может быть, всё-таки обновлять шаблон в тот момент, когда он нужен?
Когда есть реальная потребность с конкретным клиентом, конкретными данными, конкретным шаблоном?
Зачем ронять деревья в лесу, когда там никого нет  |
|
 |
Wazuuuuup Участник
Вступление в Клуб: 03.03.2014
|
Вт Мар 04, 2014 08:52   |
|
Полезность: Нет оценки
|
dbmaslov пишет: | Добрый день, коллега!
Добро пожаловать в Клуб.
Разработка интересная. Вам поможет исследование операций работающих с файлами. Таких много. К сожалению сейчас нет под рукой словаря данных. Посмотрите через поиск в текстах операций словосочетание stdio.open.
У меня встречные вопросы:
1. как вы будете сверять файлы? не уверен, что используемый механизм в ЦФТ даст вам много информации о файле (максимум размер, а дату модификации скорее всего не получить).
2. не проще ли все шаблоны держать на централизованном сетевом диске и централизованно их обновлять? |
Random пишет: | Что касается самой задачи.
Вам не кажется, что обновлять шаблоны только для того, чтобы они были верной версии - это несколько бессмысленное занятие?
Может быть, всё-таки обновлять шаблон в тот момент, когда он нужен?
Когда есть реальная потребность с конкретным клиентом, конкретными данными, конкретным шаблоном?
Зачем ронять деревья в лесу, когда там никого нет Smile |
Коллеги, спасибо за ответы!
По поводу ваших вопросов:
1. Актуализация и хранение шаблона необходимы для устранения затрат на постоянное подтягивание шаблонов с сервера. Сами шаблоны у нас модифицируются крайне редко, поэтому затраты на актуализацию будут меньше, чем на постоянное скачивание. И самое главное, это требование безопасности - избавиться от централизованного хранилища на сервере, на которое будут все ломиться.
2. Сама актуализация будет происходить по такой схеме: изначально создается справочник с записями по каждому шаблону вида:
Код шаблона
Версия
Каталог шаблона у пользователя
Каталог шаблона на сервере
Наименование файла шаблона
У пользователя шаблоны будут хранится локально в определенной папке вместе с файлом версий шаблонов. В этом файле построчно хранятся записи типа "Код шаблона - версия шаблона".
Актуализация будет происходить в момент вызова операции выполнения отчета.
Сравнение будет происходить путем сравнения версии из справочника и версии из файла на клиенте. Думаю еще добавить сравнение размеров файла.
Проблема в том, что я думал уместить все в одну библиотеку, а в библиотеках, как известно, нет ни проверки ни клиент-скрипта... Видимо придется писать отдельную операцию.
По поводу того, что придется дожидаться тела операции: у нас отчеты вынесены в отдельный справочник(он потом выносится в отдельный пункт меню навигатора), при этом часть отчетов расположены в других местах и вызываются они через PLPCALL. Есть вариант создать для остальных отчетов такие же операции, и в них перед вызовом производить актуализацию, но очень хотелось бы избежать этого... |
|
 |
Alexsey Эксперт
Вступление в Клуб: 06.09.2007
|
Вт Мар 04, 2014 10:23   |
|
Полезность: Нет оценки
|
А что мешает собрать строку для запуска операции динамически?
Например сделали несколько операций, это ладно. А далее строку для запуска собираете какой-либо функцией какой-нибудь библиотеки строку для запуска и запускаете ее в клиент-скрипте, он как раз может дождаться выполнения операции и далее дернуть необходимый функционал. В результате получите единую точку вызова
Как раз получится то, что писал Ramdom. Вы говорите клерку позвонить серверу и подождать его ответа, в зависимости от ответа выполнить следующие действия. _________________ всегда есть как минимум 2 выхода |
|
 |
Wazuuuuup Участник
Вступление в Клуб: 03.03.2014
|
Вт Мар 04, 2014 13:26   |
|
Полезность: Нет оценки
|
Сразу извиняюсь - теги чего-то не тянутся =\
Admin пишет: | В примерах кода не пишите слово CODE в квадратных скобках и все получится. Я исправил |
Решил сделать все в одной операции, в которую достаточно передать код шаблона.
Уткнулся в ту же самую проблему с отказом открытия файла =\
Установил проверки на Клиент,Сервер. Создал параметр типа FILE$LOAD и параметр для приема кода шаблона.
Проверка:
Код: |
begin
if p_message = 'DEFAULT' then
P_TEMPLATE_CODE := 'GA_PRN_OTN';
P_FILE_CHECK.[SRC_TYPE] := false;
P_FILE_CHECK.[DST_TYPE] := true;
P_FILE_CHECK.[DST_DELETE] := true;
P_FILE_CHECK.[SRC_PATH] := ::[GA_TEMPLATE_REPL](CODE = P_TEMPLATE_CODE).[CLIENT_PATH];
vTemplateFileName := ::[GA_TEMPLATE_REPL](CODE = P_TEMPLATE_CODE).[TEMPLATE_FILE];
P_FILE_CHECK.[SRC_NAME] := replace(vTemplateFileName,'.xlt','_version.txt');
P_FILE_CHECK.[DST_PATH] := [SYSTEM_PARAMS]::[GET]('PATH',null);
P_FILE_CHECK.[DST_NAME]:=P_FILE_CHECK.[SRC_NAME]||'_'||utils.session_id;
elsif p_message = 'VALIDATE' then
null;
end if;
end;
|
И в теле:
Код: |
begin
vFile := stdio.open(P_FILE_CHECK.[DST_PATH],P_FILE_CHECK.[DST_NAME],'r');
dbms_output.put_line('vFile := '||vFile);
stdio.close(vFile);
end;
|
Файл на клиенте лежит в каталоге C:\123\ с именем файла GA_PRN_OTN_version.txt
При попытке выполнения падает с ошибкой "[./GA_PRN_OTN_version.txt_000A85650001] Файл не найден" |
|
 |
Random Эксперт
Вступление в Клуб: 27.06.2011
|
Ср Мар 05, 2014 05:40   |
|
Полезность: 1
|
Wazuuuuup пишет: | Сразу извиняюсь - теги чего-то не тянутся =\
Admin пишет: | В примерах кода не пишите слово CODE в квадратных скобках и все получится. Я исправил |
Решил сделать все в одной операции, в которую достаточно передать код шаблона.
Файл на клиенте лежит в каталоге C:\123\ с именем файла GA_PRN_OTN_version.txt
При попытке выполнения падает с ошибкой "[./GA_PRN_OTN_version.txt_000A85650001] Файл не найден" |
Что-то не понимаю я, как это - достаточно передать параметр.
Выполняете вы операцию как? просто вызовом типа ::[ТРА-Та-Та].RECEIVE_FILE(p_file) ? Если так, то как раз вы пытаетесь сервер заставить сбегать в офис, даже не сообщяя ему об адресе офиса.
Ещё раз - для выполнения копирования файла НЕОБХОДИМО поднятие экранной формы операции.
Поднятие ЭФ происходит только с помощью АРМ Навигатор.
Это означает, что вы не можете копировать файлы с клиента на сервер, например, в операциях, исполняемых с помощью Oracle Jobs, как минимум - с помощью синтаксиса plp-call
Удобнее всего не работать с FILE$LOAD напрямую, этот контрол не особенно гибок.
Я повторю ещё раз - копирование файла осуществляется МЕЖДУ обработкой секции валидации и секции тела. То есть когда вы нажимаете кнопку OK, то, если у кнопки установлен признак CheckValidate, сначала будет обработана секция валидации, и лишь затем копирование файла, и потом - тело операции.
А прямым вызовом операции в теле другой операции вы переходите сразу к телу этой операции. Короче, это сложно, не грейте голову.
Удобнее всего работать с операциями, запускаемыми через вывод в буфер сессии.
Если привести аналогию, то вы отправляете клерку письмо с просьбой доставить вам файл. Однако вы не можете сразу после отправки письма бежать в почтовый ящик и работать с файлом, его там ещё нет.
Ведь на самом деле вы ничего не копируете. Вы выводите в буфер сессии некую строчку, которая сама по себе ничего не значит. АРМ Навигатор имеет соединение с сервером. В момент какого-либо события АРМ обрабатывает VB-скрипт у контрола, если он есть, потом в зависимости от установок доп.свойств - функцию Main в VBS или секцию валидации на сервере.
Просто касательно буфера сессии есть некие договорённости - после того, как вызов операции с сервера завершится, прочитать буфер сессии, разобрать и если синтаксис похож на синтаксис PLPCALL, попытаться разобраться в строчке и запустить операцию.
Именно об этом я говорил, когда писал о бикфордовом шнуре пару сообщений назад.
Управление не вернётся в АРМ Навигатор, точнее, АРМ Навигатор не будет разбирать буфер сессии, пока не отработает вся операция на сервере( вся секция валидации ) или вся функция VBS.
Итак, вот операция:
Групповая;
доп.свойства: выводит команды в буфер сессии
При загрузке: Сервер, Клиент;
При смене - Клиент, Сервер.
На ЭФ: текстовое поле для ввода пути файла на клиенте (у клерка), связанное с переменной V_FILE, в VBS известное как T_FILE.
Кнопка "Поехали", в VBS известная как B_GO; у кнопки установлен признак CheckValidate.
Кнопка "Проверить", в VBS известная как B_CHECK; у кнопки установлен признак CheckValidate.
VBS: Код: |
Public Function Main(LastControl)
Main = true
' функция должна быть, но не обязана выполнять что-либо
End Function
sub B_GO_OnClick
Form1.ScriptServerValidate OK, "SERVER_LOAD"
end sub
sub B_CHECK_OnClick
Form1.ScriptServerValidate OK, "SERVER_CHECK"
end sub
|
Секция валидации:
Код: |
pragma macro(CPFC, 'REPS_DATA.COPYFILES');-- также есть такие операции в REPS, RUNTIME и, кажется, в DOCUMENT
pragma macro(CPFS, 'REPS_DATA COPYFILES');
var vPath varchar2(32767);
var vFilename varchar2(32767);
if p_message = 'VALIDATE' and p_info = 'SERVER_LOAD' then
vPath := substr(v_file, 1, instr(v_file, '\', -1)-1); -- путь до каталога с файлом
vFilename := substr(v_file, instr(v_file, '\', -1)+1); -- имя файла
&CPFC.idx := nvl(&CPFC.tbl_F$L.last,0);
-- client
&CPFC.tbl_F$L(&CPFC.idx+1).[SRC_NAME] := vFilename;
&CPFC.tbl_F$L(&CPFC.idx+1).[SRC_PATH] := vPath;
&CPFC.tbl_F$L(&CPFC.idx+1).[SRC_TYPE] := false;
&CPFC.tbl_F$L(&CPFC.idx+1).[SRC_DELETE] := false;
-- server
&CPFC.tbl_F$L(&CPFC.idx+1).[DST_NAME] := vFilename;
&CPFC.tbl_F$L(&CPFC.idx+1).[DST_PATH] := '.'; -- это путь на сервере, файл будет доступен через ./file_name
&CPFC.tbl_F$L(&CPFC.idx+1).[DST_TYPE] := true;
&CPFC.tbl_F$L(&CPFC.idx+1).[DST_DELETE] := false;
&CPFC.idx := 0;
stdio.put_line_buf('<% CALL '||&CPFS||' ' || nvl(::[SYSTEM]%id, 1) || ' %>');
elsif p_message = 'VALIDATE' and p_info = 'SERVER_CHECK' then
vFilename := substr(v_file, instr(v_file, '\', -1)+1); -- имя файла
if ::[REPS_DATA].[LIB_FILE].FileExists('./'||vFilename) then -- не хочу приводить реализацию функции, глянь сам
debug_pipe('Ура-ура!',0);
else
debug_pipe('Эх... что-то пошло не так...',0);
end if;
end if;
|
|
|
 |
Wazuuuuup Участник
Вступление в Клуб: 03.03.2014
|
Ср Мар 05, 2014 09:20   |
|
Полезность: Нет оценки
|
Спасибо за развернутый ответ, теперь понятно.
Random пишет: | Wazuuuuup пишет: | Сразу извиняюсь - теги чего-то не тянутся =\
Admin пишет: | В примерах кода не пишите слово CODE в квадратных скобках и все получится. Я исправил |
Решил сделать все в одной операции, в которую достаточно передать код шаблона.
Файл на клиенте лежит в каталоге C:\123\ с именем файла GA_PRN_OTN_version.txt
При попытке выполнения падает с ошибкой "[./GA_PRN_OTN_version.txt_000A85650001] Файл не найден" |
Что-то не понимаю я, как это - достаточно передать параметр. |
Я имел ввиду, что в пользователь вводит только код шаблона, имена файлов вводятся в коде.
Random пишет: | Выполняете вы операцию как? просто вызовом типа ::[ТРА-Та-Та].RECEIVE_FILE(p_file) ? Если так, то как раз вы пытаетесь сервер заставить сбегать в офис, даже не сообщяя ему об адресе офиса. |
Операцию выполняю через навигатор. Но потом планировал так и сделать, спасибо что предупредили)
Но проблемы это не отменяет - операция, которую я описал в предыдущем посте, так и не работает. Может проблема в том, что я сам контрол FILE_$LOAD не вынес на форму? На форме у меня только текстовое поле для ввода кода шаблона. |
|
 |
|
|
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
|
|