CftClub.ru
Клуб специалистов ЦФТ-Банк

Работа с файлами на стороне клиента

 
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Уроки ЦФТ-Банк для начинающих
Предыдущая тема :: Следующая тема  
Автор Сообщение
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 пишет:
Всем здравствуйте!
Появилась необходимость создать механизм репликации файлов шаблонов отчетов на рабочие места пользователей.

Что касается самой задачи.
Вам не кажется, что обновлять шаблоны только для того, чтобы они были верной версии - это несколько бессмысленное занятие?

Может быть, всё-таки обновлять шаблон в тот момент, когда он нужен?
Когда есть реальная потребность с конкретным клиентом, конкретными данными, конкретным шаблоном?

Зачем ронять деревья в лесу, когда там никого нет Smile
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 не вынес на форму? На форме у меня только текстовое поле для ввода кода шаблона.
Показать сообщения:   
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Уроки ЦФТ-Банк для начинающих Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Рейтинг@Mail.ru