Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Горячая тема (более 10 ответов) подмена функций глобального модуля (число прочтений - 7878 )
unnamed
Full Member
***
Отсутствует


0x1c = 28

Сообщений: 166
Местоположение: Chelyabinsk
Зарегистрирован: 01. Ноября 2007
Пол: Мужской
подмена функций глобального модуля
12. Февраля 2008 :: 10:02
Печать  
Даже не знаю, в какую ветку было бы это более правильно засунуть.. Поэтому сюда, благо пока из использующего функционала в решении вопроса темы сообщения больше всего пробовал использовать Formex. Улыбка.

Итак, задача состоит в том, чтобы иметь возможность при необходимости вызывать УЖЕ имеющуюся в глобальнике функцию из ВНЕШНЕГО файла, если она там описана. Если не описана - то использоваться должна функция, описанная в глобальном модуле конфигурации.

Задача возникла из-за необходимости внедрить измененный процесс в уже существующей конфигурации и по возможности отлаживать его во время внедрения (без остановки торгового процесса и выхода всех из конфигурации. Сложность в том, что неизвестно есть ли эта функция или нет во внешнем файле, хотелось бы как-то проверить ее существование и тогда уже вызывать или нет + в том, что 1с сообщает об ошибке, если видит вызов несуществующей функции (syntax error).

Выход в тем, чтобы держать эту функцию постоянно во внешнем файле не подходит из-за разных соображений (секурность, наличие постоянного кода во внешнем файле для просмотра и тп). Вот как я попробовал решить эти вопросы:

Пробовал просто тупо описать во внешнем файле уже существующую и описанную в глобальнике функцию второй раз (так-же, c теми же параметрами и словом Экспорт) - загружает, не выдает ошибок, но реально везде, где используется эта функция, выполняется функция из глобальника. ОбновитьДанныеМетодовГлобальногоМодуля() тоже не приносит результатов.

Надумал пока что следующее:

1) При загрузке глобального модуля

Код
Выбрать все
глдопФункции=""; (переменная, описанная в глобальном модуле)
Попытка
  Сервис = СоздатьОбъект("Сервис");
  глДопМодуль = Сервис.ДобавитьГлобальныйМодуль("#ЗагрузитьИзФайла headmod.prm");
  глдопФункции="headmod,";
Исключение
КонецПопытки;
Если глдопФункции<>"" Тогда
  Попытка
    тмп=Шаблон("[глДопПриначалеРаботыСистемы()]");
    глдопФункции=глдопФункции+тмп;
  Исключение
  КонецПопытки;
КонецЕсли;
 



2) в той самой функции ГЛОБАЛЬНОГО модуля дописать блок тестирующей существование внешней функции-дубля, если есть - передаем ей управление.

Код
Выбрать все
Функция ентРасчета = "",ТабВиртРезерва = "",фл=0) Экспорт
  Попытка
    Если Найти(глдопФункции,"глРазыменоватьГлавныйАртикул")<>0 Тогда
      тмп="";
      тмп=Число(Шаблон("[глДопРазыменоватьГлавныйАртикул(РазыменуемыйЭлемент,Количество,Склад,ТабТоваров,МоментРасчета,ТабВиртРезерва,фл)]"));
      Возврат тмп;
    КонецЕсли;
  Исключение
  КонецПопытки;
[...] далее текст функции
 



3) во внешнем файле (headmod.prm) всегда должна быть описана функция, возвращающая признак использования внешних функций:

Код
Выбрать все
=== headmod.prm ====
Функция глДопПриначалеРаботыСистемы() Экспорт
Возврат "глРазыменоватьГлавныйАртикул";
КонецФункции
// и есс-но сама функция глобального модуля с изменениями и другим названием:
Функция МоментРасчета = "",ТабВиртРезерва = "",фл=0) Экспорт // фл=1 строгое соответствие
[...] далее текст функции
 





Во всем этом мне не нравится...

1) Необходимость изменения текста исходной функции в глобальнике. Ну, чувствую, от этого не избавиться, если вдруг такой функционал по замене не появится в Formexe.

2) Если кто-то из разработчиков случайно забудет и сохранит файл headmod.prm без функции глДопПриначалеРаботыСистемы, в окно сообщений 1с ВСЕГДА выдастся ошибка, это некрасиво. Пробовал избежать этого с помощью использования вместо функции Шаблон([ модуля:
Код
Выбрать все
тмп=СоздатьОбъект("ВыполняемыйМодуль");
;
тмп.КомпилироватьМодуль();
тмп.ВыполнитьМодуль();
 



а так же с использованием метода КомпилироватьИВыполнитьМодуль - все равно, выдается сообщение "== syntax error".

1с++ я занимаюсь совсем недавно, может быть я не знаю чего-нибудь про обработку т.н. "exception", с помощью которых можно было бы избавиться от сообщения?

Копал так-же в сторону функционала Событие_НеобработаннаяОшибка, обычные ошибки она "ловит" на лету, ошибки же, возникающие внутри Шаблона и ВыполняемогоМодуля - нет (точнее, при выполняемом модуле сперва показывается сообщение "== syntax error", а затем уже срабатывает событие).

Есть ли у кого мысли по этому поводу, направления, о которых можно поразмыслить?


« Последняя редакция: 12. Февраля 2008 :: 11:46 - unnamed »  
Наверх
ICQ  
IP записан
 
vandalsvq
1c++ power user
Отсутствует


Я всего лишь als-особиратель
;-)

Сообщений: 2487
Местоположение: Уфа
Зарегистрирован: 18. Июля 2007
Пол: Мужской
Re: подмена функций глобального модуля
Ответ #1 - 12. Февраля 2008 :: 18:12
Печать  
Не стал сильно углуб##тьсяю.. но в данном вопросе лучше посмотреть в сторону 1С++
а именно тебе понадобится класс "Перехватчик" (чтобы глб процедуры хапать в модуль обработки), "Информатор" чтобы проверять если подобная проца или функция в модуле или нет, ну и соответственно выполняемый модуль или же сервис.выполнитьпроцедуру... ну наверное так... хотя может я просто не разобрался до конца с задачей
  

Отхожу от дел. Долго и мучительно.
Наверх
IP записан
 
unnamed
Full Member
***
Отсутствует


0x1c = 28

Сообщений: 166
Местоположение: Chelyabinsk
Зарегистрирован: 01. Ноября 2007
Пол: Мужской
Re: подмена функций глобального модуля
Ответ #2 - 13. Февраля 2008 :: 10:17
Печать  
По классу перехвачик так и не разобрался. Сложно как-то там все.

Простейшие функции он перехватывает (предопределенные там всякие из глобальника), а как перехватить обычную функцию со словом Эксперт, определенную в глобальном модуле, не ясно. Пробовал прописать
Код
Выбрать все
Функция оваров,МоментРасчета = "",ТабВиртРезерва = "",фл=0) Экспорт
	Сообщить("КОП::СобытиеГМ_Разыменование = <"+ТипЗначенияСтр(РазыменуемыйЭлемент)+">");
	Возврат езерва,фл);

КонецФункции
 

- не помогло.

По классу Информатор не вижу, как его использовать для проверки, скажем, существования функции в дополнительном глобальнике (да даже просто глобальнике) - в методах МетодСуществует(ПроверяемыйОбъект, ИмяМетода) и т.п. не представляю, что указывать в качестве ПроверяемыйОбъект для глобального модуля. Контекст пробовал - пустая ТЗ вернулась в ответ на ПолучитьТаблицуМетодов.

  
Наверх
ICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: подмена функций глобального модуля
Ответ #3 - 13. Февраля 2008 :: 10:54
Печать  
unnamed писал(а) 13. Февраля 2008 :: 10:17:
По классу перехвачик так и не разобрался. Сложно как-то там все.

Зря ты так, сложность только на первый взгляд Улыбка из-за особенности задачи перехвата Улыбка

Перехватчик не умеет подменять произвольные глобальные функции, он работает только с событиями и их обработчиками!
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
unnamed
Full Member
***
Отсутствует


0x1c = 28

Сообщений: 166
Местоположение: Chelyabinsk
Зарегистрирован: 01. Ноября 2007
Пол: Мужской
Re: подмена функций глобального модуля
Ответ #4 - 13. Февраля 2008 :: 11:07
Печать  
artbear писал(а) 13. Февраля 2008 :: 10:54:
Зря ты так, сложность только на первый взгляд Улыбка из-за особенности задачи перехвата Улыбка

Перехватчик не умеет подменять произвольные глобальные функции, он работает только с событиями и их обработчиками!


Ну на уровне подмены событий стандартных предопределенных функций / описанных в хэлпнике событий у меня получилось...
А на тему изначального вопроса, значит, это мне помочь никак не может? 
Жалко... Вот бы было здорово еслиб formex при загрузке заменял функции из глобальника на загруженные извне, если они там так же называются...

Да, кстати, Артур, в процессе поисков по темам нашел заброшенную ветку про обсуждение возможности создания/развития объекта ПерехватчикВстроенныхМетодов1С , там какая-то дальнейшая история была у этого проекта?

  
Наверх
ICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: подмена функций глобального модуля
Ответ #5 - 13. Февраля 2008 :: 11:27
Печать  
unnamed писал(а) 13. Февраля 2008 :: 11:07:
Да, кстати, Артур, в процессе поисков по темам нашел заброшенную ветку про обсуждение возможности создания/развития объекта ПерехватчикВстроенныхМетодов1С , там какая-то дальнейшая история была у этого проекта?

Пока эта тема отложена Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: подмена функций глобального модуля
Ответ #6 - 13. Февраля 2008 :: 11:32
Печать  
unnamed писал(а) 13. Февраля 2008 :: 11:07:
Вот бы было здорово еслиб formex при загрузке заменял функции из глобальника на загруженные извне, если они там так же называются...

Тут два подхода у 1С, если я не ошибаюсь.
1) Если вызываемый метод находится в том же модуле, что и метод, из которого вызываем, тогда идет работа напрямую, через п-код, его совсем не просто подменить, я даже не знаю, где копать.
Т.е. это вызов одного глобального метода из другого.
2) А если идет вызов метода глобальника из любого другого модуля, тогда уже можно пытаться перехватить и подменить этот вызов.
ЗЫ для максимальной достоверности нужно АльФ-а пытать Улыбка
ИМХО он точно знает
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
АЛьФ
FormEx developer
1c++ developer
Отсутствует



Сообщений: 1538
Местоположение: Санкт-Петербург
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: подмена функций глобального модуля
Ответ #7 - 13. Февраля 2008 :: 17:17
Печать  
Насколько я понимаю, надо, чтобы методы дополнительного глобальника перекрывали методы основного глобальника. Достичь этого достаточно легко. Надо всего лишь сделать, чтобы порядок загрузки глобальников был "обратным". Т.е. сейчас модули загружаются последовательно: 0, 1, 2 и т.д. И именно в этом порядке при компиляции локального модуля идет поиск процедур. Как только процедура найдена, ее вызов записывается в п-код и потом выполняется. Отсюда и получается, что метод основного глобальника не перекрывается, т.к. он всегда стоит первым в списке загрузки.
Для решения сабжа надо сделать, чтобы при загрузке очередного дополнительного глобальника все уже загруженные глобальники сдвигались "назад", т.е. порядок получался бы обратным: 2, 1, 0. Тут компилятор автоматом возьмет метод из последнего загруженного глобальника.
В принципе, все это реализуемо. Проблема в том, что у меня лично на это времени пока нет.
  

FormEx developer
Наверх
www  
IP записан
 
unnamed
Full Member
***
Отсутствует


0x1c = 28

Сообщений: 166
Местоположение: Chelyabinsk
Зарегистрирован: 01. Ноября 2007
Пол: Мужской
Re: подмена функций глобального модуля
Ответ #8 - 13. Февраля 2008 :: 17:53
Печать  
Цитата:
Достичь этого достаточно легко. Надо всего лишь сделать, чтобы порядок загрузки глобальников был "обратным". В принципе, все это реализуемо. Проблема в том, что у меня лично на это времени пока нет.


Да, именно этого и хотелось. Ну чтож... Значит, надежда в будущем есть...
Может куда-нить дописать в хотелки? Улыбка Я так прикинул, что помимо упомянутых в первом сообщений целей, эта функция позволила бы, в принципе, при наличии остальных возможностей типа Перехватчика и т.д., при дополнении всего нескольких строк в глобальный модуль иметь возможность извне программно дополнять/менять функционал конфигурации, не меняя ее по всем кускам кода. Что иногда так весьма полезным может оказаться для типовых конфигураций например, чтобы их возможности было легче расширять и при этом легче обновлять при выходе измененной версии от 1с.
  
Наверх
ICQ  
IP записан
 
Nick
God Member
*****
Отсутствует



Сообщений: 1599
Местоположение: г.Новокузнецк
Зарегистрирован: 21. Февраля 2007
Пол: Мужской
Re: подмена функций глобального модуля
Ответ #9 - 15. Февраля 2008 :: 02:24
Печать  
unnamed писал(а) 13. Февраля 2008 :: 17:53:
Цитата:
Достичь этого достаточно легко. Надо всего лишь сделать, чтобы порядок загрузки глобальников был "обратным". В принципе, все это реализуемо. Проблема в том, что у меня лично на это времени пока нет.


Да, именно этого и хотелось. Ну чтож... Значит, надежда в будущем есть...
Может куда-нить дописать в хотелки? Улыбка Я так прикинул, что помимо упомянутых в первом сообщений целей, эта функция позволила бы, в принципе, при наличии остальных возможностей типа Перехватчика и т.д., при дополнении всего нескольких строк в глобальный модуль иметь возможность извне программно дополнять/менять функционал конфигурации, не меняя ее по всем кускам кода. Что иногда так весьма полезным может оказаться для типовых конфигураций например, чтобы их возможности было легче расширять и при этом легче обновлять при выходе измененной версии от 1с.


+ Такая хотелка: Можно как нибудь потом обращатся к замещенным процедурам? через префикс например?
т.е. пишешь свою процедуру:

Процедура глВыполнить()
     ..............
     глМ1.глВыполнить()
КонецПроцедуры

  
Наверх
ICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: подмена функций глобального модуля
Ответ #10 - 15. Февраля 2008 :: 05:03
Печать  
Все пожелания в багзиллу, раздел ФормЕкс.
Иначе забудем, потеряем и т.д. Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
ADirks
1c++ developer
1c++ moderator
Отсутствует


А нужны ли мы нам?

Сообщений: 692
Местоположение: Новосибирск
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: подмена функций глобального модуля
Ответ #11 - 15. Февраля 2008 :: 07:07
Печать  
Цитата:
+ Такая хотелка: Можно как нибудь потом обращатся к замещенным процедурам? через префикс например?
т.е. пишешь свою процедуру:

Процедура глВыполнить()
     ..............
     глМ1.глВыполнить()
КонецПроцедуры

Даешь наследование глобальных модулей!  И полиморфизм тогда уже до кучи!   Смех
  
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: подмена функций глобального модуля
Ответ #12 - 15. Февраля 2008 :: 09:42
Печать  
И инкапсуляцию, обязательно.
...
...
...

Ужоснах. Смех
  

De quelle planète es-tu?
Наверх
 
IP записан
 
Nick
God Member
*****
Отсутствует



Сообщений: 1599
Местоположение: г.Новокузнецк
Зарегистрирован: 21. Февраля 2007
Пол: Мужской
Re: подмена функций глобального модуля
Ответ #13 - 15. Февраля 2008 :: 09:49
Печать  
kms писал(а) 15. Февраля 2008 :: 09:42:
И инкапсуляцию, обязательно.
...
...
...

Ужоснах. Смех


Смейтесь смейтесь я ещё с индексированной таблицей не закончил    Смех
  
Наверх
ICQ  
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: подмена функций глобального модуля
Ответ #14 - 15. Февраля 2008 :: 10:06
Печать  
Nick писал(а) 15. Февраля 2008 :: 09:49:
Смейтесь смейтесь я ещё с индексированной таблицей не закончил    Смех

Не, теперь проблемы с ИТ не раньше следующего года по плану.
Впрочем, если что - велкам.

unnamed

Может все же подумаешь, не вынести ли функционал в классы?
Там давно эти вопросы решены, кроме одного.
  

De quelle planète es-tu?
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать