Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Горячая тема (более 10 ответов) сп.ВыбратьЗначение(...) - как подменить данный метод своей процедуркой? (число прочтений - 7420 )
Ковалев Андрей
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 36
Зарегистрирован: 03. Февраля 2010
сп.ВыбратьЗначение(...) - как подменить данный метод своей процедуркой?
29. Сентября 2011 :: 13:28
Печать  
По всей конфигурации натыкано вот таких фрагментиков куча:

сп=создатьОбъект("СписокЗначений");
сп.выбратьЗначение(...)

Мне необходимо перехватить "...ВыбратьЗначение..." для переменных типа "СписокЗначений" и заменить на свою процедурку.

Может кто подскажет, как можно это сделать?
  
Наверх
 
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: сп.ВыбратьЗначение(...) - как подменить данный метод своей процедуркой?
Ответ #1 - 29. Сентября 2011 :: 15:20
Печать  
Разве что переоределить список значений своим классом и переписать все методы в самом классе.
  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: сп.ВыбратьЗначение(...) - как подменить данный метод своей процедуркой?
Ответ #2 - 30. Сентября 2011 :: 03:29
Печать  
Eprst писал(а) 29. Сентября 2011 :: 15:20:
Разве что переоределить список значений своим классом и переписать все методы в самом классе.


Зачем переопределять ВСЕ методы?

Переопределяем класс СписокЗначений как наследника от ValueList.
Далее переопределяем только те методы, которые действительно нужно переопределить.

Если где-то нужен обычный список значений - создаем его через СоздатьОбъект("ValueList").
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


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

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: сп.ВыбратьЗначение(...) - как подменить данный метод своей процедуркой?
Ответ #3 - 30. Сентября 2011 :: 04:24
Печать  
Satans Claws писал(а) 30. Сентября 2011 :: 03:29:
Переопределяем класс СписокЗначений как наследника от ValueList.
Далее переопределяем только те методы, которые действительно нужно переопределить.

Если где-то нужен обычный список значений - создаем его через СоздатьОбъект("ValueList").

Такой способ подмены не всегда хорошо работает Печаль
В свое время на форуме проводились исследования по подмене типовых объектов 1С на свои объекты, были проблемы.
Ветки, к сожалению, не помню Печаль
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Ковалев Андрей
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 36
Зарегистрирован: 03. Февраля 2010
Re: сп.ВыбратьЗначение(...) - как подменить данный метод своей процедуркой?
Ответ #4 - 30. Сентября 2011 :: 06:49
Печать  
Спасибо за советы. Сегодня попробую, отпишу.

Кстати, может дадите еще дельный совет, т.к.очень может быть, что зря все это делаю.
Использую в конфигурации плавающие формы и в результате там, где используется сп.ВыбратьЗначение(...), менюшка с выбором подстраивается не в месте, где щелкаешь мышкой, а там, где открылась последняя плавающая форма
  
Наверх
 
IP записан
 
Dmitry The Wing
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 839
Местоположение: Где-то в Сибири
Зарегистрирован: 18. Августа 2009
Пол: Мужской
Re: сп.ВыбратьЗначение(...) - как подменить данный метод своей процедуркой?
Ответ #5 - 03. Октября 2011 :: 01:36
Печать  
Ковалев Андрей писал(а) 30. Сентября 2011 :: 06:49:
Использую в конфигурации плавающие формы и в результате там, где используется сп.ВыбратьЗначение(...), менюшка с выбором подстраивается не в месте, где щелкаешь мышкой, а там, где открылась последняя плавающая форма
Это известный неустранимый баг плавающей формы...
  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: сп.ВыбратьЗначение(...) - как подменить данный метод своей процедуркой?
Ответ #6 - 03. Октября 2011 :: 04:06
Печать  
artbear писал(а) 30. Сентября 2011 :: 04:24:
Такой способ подмены не всегда хорошо работает Печаль
В свое время на форуме проводились исследования по подмене типовых объектов 1С на свои объекты, были проблемы.
Ветки, к сожалению, не помню Печаль


Сходу могу предположить только проблемы с методом Выгрузить() - скорее всего, 1Ска автоматом создасть базовый объект (соответствующий "ValueList" в данной структуре).
  
Наверх
 
IP записан
 
Ковалев Андрей
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 36
Зарегистрирован: 03. Февраля 2010
Re: сп.ВыбратьЗначение(...) - как подменить данный метод своей процедуркой?
Ответ #7 - 03. Октября 2011 :: 07:12
Печать  
Dmitry The Wing писал(а) 03. Октября 2011 :: 01:36:
Это известный неустранимый баг плавающей формы...


Эта проблема разрешима, но как раз "сп.выбратьЗначение(...)" и нужно заменять на другую конструкцию
  
Наверх
 
IP записан
 
Ковалев Андрей
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 36
Зарегистрирован: 03. Февраля 2010
Re: сп.ВыбратьЗначение(...) - как подменить данный метод своей процедуркой?
Ответ #8 - 11. Октября 2011 :: 14:21
Печать  
Подменил 1Совский объект "СписокЗначений" своим классом (как наследника от "ValueList"). Переписал метод "ВыбратьЗначение". Работает.    
Но есть своя засада.

Если где-нибудь в коде используется язык запросов и есть конструкция:

     |Условие(зКлиент в спОдниИТеЖеКлиенты);

Где "спОдниИТеЖеКлиенты" имеет тип "СписокЗначений", данное условие всегда возвращает 0. Не знаю, чего с этим делать  Плачущий
  
Наверх
 
IP записан
 
mszsuz
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 33
Зарегистрирован: 18. Октября 2010
Re: сп.ВыбратьЗначение(...) - как подменить данный метод своей процедуркой?
Ответ #9 - 11. Октября 2011 :: 17:37
Печать  
У меня на 27-м (DBF) запрос с такими исходными данными вообще молча схлопывает 1С.

Как далеко готов зайти?

Вот вариант:
1. Добавить в твой класс "СписокЗначений" экспортную переменную
БазовыйСписокЗначений = вирт().ПолучитьБазовыйКласс();
2. Переопределить Запрос своим классом (аналогично как со СпискомЗначений), в котором переопределяем .Выполнить();
3. В этом методе .Выполнить(ТекстЗапроса) парсим полученный текст запроса - ищем строку "Условие (... В ...)", получаем имя переменной "спОдниИТеЖеКлиенты".
4. Проверяем в контексте выполнения запроса эту переменную. Если Информатор.ТипЗначенияСтрВнутр(Конт.спОдниИТеЖеКлиенты) = "CComponentClass",  то заменяем в тексте запроса
|Условие(зКлиент в спОдниИТеЖеКлиенты);
на
|Условие(зКлиент в спОдниИТеЖеКлиенты.БазовыйСписокЗначений);
и скармливаем исправленный текст запроса оригинальному методу Выполнить().

  
Наверх
 
IP записан
 
Ковалев Андрей
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 36
Зарегистрирован: 03. Февраля 2010
Re: сп.ВыбратьЗначение(...) - как подменить данный метод своей процедуркой?
Ответ #10 - 12. Октября 2011 :: 06:42
Печать  
О, спасибо огромное.  Я тугодум, сам до этого не додумался. Попробую.  Отпишу о результатах
  
Наверх
 
IP записан
 
Ковалев Андрей
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 36
Зарегистрирован: 03. Февраля 2010
Re: сп.ВыбратьЗначение(...) - как подменить данный метод своей процедуркой?
Ответ #11 - 12. Октября 2011 :: 12:50
Печать  
mszsuz писал(а) 11. Октября 2011 :: 17:37:
...4. Проверяем в контексте выполнения запроса эту переменную. Если Информатор.ТипЗначенияСтрВнутр(Конт.спОдниИТеЖеКлиенты) = "CComponentClass",  то ...


Создал свой класс "Запрос" как потомок от "Query".
Переопределил метод "Выполнить(ТекстЗапроса)"
Отловил свое условие в ТекстеЗапроса и имя переменной "спОдниИТеЖеКлиенты"

Далее засада:   НЕ ПОЛУЧАЕТСЯ ПРОВЕРИТЬ В КОНТЕКСТЕ ВЫПОЛНЕНИЯ ЭТУ ПЕРЕМЕННУЮ  Плачущий

в переменной тНашаПеременная сидит имя из условия, т.е.
тНашаПеременная="спОдниИТеЖеКлиенты";

Делаю так:

РодительскийКонт = Этот(Контекст).ПолучитьКонтекстОкружения();
клИнформатор = СоздатьОбъект("Информатор");
клСервис = СоздатьОбъект("Service");
Если клСервис.ПолучитьПеременнуюКонтекста(РодительскийКонт, тНашаПеременная, знНашейПеременной)=1 Тогда
Сообщить("ура");
Сообщить(клИнформатор.ТипЗначенияСтрВнутр(знНашейПеременной));
Иначе
Сообщить("!!! ЗАСАДА !!!");
КонецЕсли;

Выводит "Засаду!!! "         Плачущий
  
Наверх
 
IP записан
 
mszsuz
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 33
Зарегистрирован: 18. Октября 2010
Re: сп.ВыбратьЗначение(...) - как подменить данный метод своей процедуркой?
Ответ #12 - 12. Октября 2011 :: 13:36
Печать  
  
Наверх
 
IP записан
 
Ковалев Андрей
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 36
Зарегистрирован: 03. Февраля 2010
Re: сп.ВыбратьЗначение(...) - как подменить данный метод своей процедуркой?
Ответ #13 - 12. Октября 2011 :: 13:59
Печать  
сделал, но там еще одна засада.  Вывело:

=== Syntax error в модуле 'unknown' 36042656
Возврат спОдниИТеЖеКлиенты<<?>>;
{(5)}: Переменная не определена (спОдниИТеЖеКлиенты)
Запрос::ПолучитьПеременнуюКонтекста(Расписание Конт=, Строка Имя=спОдниИТеЖеКлиенты) : Поле агрегатного объекта не обнаружено
Возврат ВМ._ПолучитьПеременную();


Вызов запроса на выполнение у меня в другом классе, который вызывается на выполнение из отчета.
Во блин.
  
Наверх
 
IP записан
 
Ковалев Андрей
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 36
Зарегистрирован: 03. Февраля 2010
Re: сп.ВыбратьЗначение(...) - как подменить данный метод своей процедуркой?
Ответ #14 - 12. Октября 2011 :: 14:06
Печать  
Проверил еще вариант. Срабатывает, если "спОдниИТеЖеКлиенты" экспортная переменная класса, где есть черный запрос.  А в моем случае это локальная переменная метода.
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать