![]() |
![]() |
![]() |
|
Таблица.ИсходнаяТаблица(...), Вызов из другого модуля. | ☑ | ||
---|---|---|---|---|
0
twilight5023
10.03.06
✎
14:23
|
Имеется внешний отчет report.ert, в нем есть таблица table, которая заполняется согласно определенному алгоритму. Пытаюсь запустить процедуру формирования этого отчета из другого модуля (call_report.ert), соответственно открываю форму ОткрытьФорму("Отчет",СписокПараметров,"report.ert");, в списке параметров передаю параметр "Автозапуск" = 1, который анализируется в report.ert, т.е. если это запуск из другого модуля, то формируем все автоматически и сохраняем файл. Однако при запуске на строке Таб.ИсходнаяТаблица("table"); он пишет не найден файл "table". Я так понимаю что поиск таблицы идет в вызвавшем модуле, а потом в общих таблицах? Можно ли как-нибудь указать чтобы таблица "table" искалась в report.ert, а не в call_report.ert?
|
|||
1
Вильям
10.03.06
✎
14:28
|
Приведи текст report.ert.
По крайней мере кусок, где ты создаешь таблицу и процедуру ПриОткрытии() |
|||
2
GrayT
10.03.06
✎
14:32
|
На всякий случай проверь имя таблицы в report.ert
|
|||
3
twilight5023
10.03.06
✎
14:33
|
[report.ert]
Процедура Сформировать() <...> Таб = СоздатьОбъект("Таблица"); Таб.ИсходнаяТаблица("table"); Таб.ВывестиСекцию("Заголовок"); Таб.Опции(0, 0, Таб.ВысотаТаблицы()); <...> < дальнейшее не ПриОткрытии(), а в коде после всех процедур в report.ert > гПараметрыВызова = Форма.Параметр; ПутьДляВыгрузки = гПараметрыВызова.Получить("ПутьДляВыгрузки"); ФайлДляВыгрузки = гПараметрыВызова.Получить("ФайлДляВыгрузки"); КодГруппы = гПараметрыВызова.Получить("КодГруппы"); Автозапуск = гПараметрыВызова.Получить("Автозапуск"); ФайлЛога = гПараметрыВызова.Получить("ФайлЛога"); ДатаКонца = гПараметрыВызова.Получить("ДатаКонца"); ДатаНачала = гПараметрыВызова.Получить("ДатаНачала"); Номенклатура = СоздатьОбъект("Справочник.Номенклатура"); Номенклатура.НайтиПоКоду(КодГруппы); ВыбТМЦ = Номенклатура.ТекущийЭлемент(); <...> // Если форма была вызвана из другой (запущено роботом) - запускаем формирование Если ПустоеЗначение(Автозапуск)=0 Тогда Если Автозапуск = 1 Тогда Сформировать(); Форма.Закрыть(0); КонецЕсли; КонецЕсли; [call_report.ert] СписокПараметров = СоздатьОбъект("СписокЗначений"); <...> СписокПараметров.ДобавитьЗначение(1, "Автозапуск"); ОткрытьФорму("Отчет",СписокПараметров,"report.ert"); |
|||
4
twilight5023
10.03.06
✎
14:35
|
(2) Имя таблицы правильно, если просто ткнуть кнопку на которую привязано Сформировать() - все работает, а вот если вызывать из call_report.ert, то он почему-то ищет таблицу с именем table сначала в call_report.ert, потом в общих таблицах, а потом в файле. Естественно не находит, т.к. она находится в вызываемом report.ert, в принципе не проблема, можно вынести таблицу во внешний файл или перенести в общие, но как-то нехорошо это ;)
|
|||
5
twilight5023
10.03.06
✎
14:36
|
Просто не пойму почему он ищет таблицу в вызвавшем модуле, а не в том код которого исполняется на данный момент. Можно как-то в ИсходнаяТаблица(...) указать чтобы таблица бралась именно из report.ert?
|
|||
6
Тык
10.03.06
✎
14:40
|
Определи Таб на уровне модуля
|
|||
7
twilight5023
10.03.06
✎
14:44
|
(6)
[report.ert] Перем Таб; <...> Процедура Сформировать() <...> Таб = СоздатьОбъект("Таблица"); Таб.ИсходнаяТаблица("table"); Таб.ВывестиСекцию("Заголовок"); Таб.Опции(0, 0, Таб.ВысотаТаблицы()); <...> Результат тот же самый. Не там он ищет. |
|||
8
Shaman100M
10.03.06
✎
14:45
|
(7) Перенеси "код после всех процедур" в процедуру ПриОткрытии() - она выполняется последней.
|
|||
9
twilight5023
10.03.06
✎
14:47
|
(8) А смысл? Код после всех процедур выполняется, Сформировать() запускается. Только он таблицу не там ищет.
|
|||
10
twilight5023
10.03.06
✎
14:48
|
(8) Оп-па... Ты гений ;) Если перенести все это в ПриОткрытии(), то работает. Интересно, а почему так? Разницы ведь вроде никакой?
|
|||
11
Shaman100M
10.03.06
✎
14:49
|
(9) ИМХО, может это связано именно с последовательностью событий при открытии формы?
|
|||
12
Shaman100M
10.03.06
✎
14:50
|
(11) Но ПриОткрытии() выполняется самой последней, после ВводНового(), ВводНаОсновании() и операторов в конце модуля.
|
|||
13
twilight5023
10.03.06
✎
14:52
|
(11) Ты прав... оказалось связано, но как-то уж очень неявно. Из описания метода исходная таблица: "Переназначает в качестве исходной таблицы-шаблона одну из таблиц той формы, в программном модуле которой запущена данная процедура. Имя таблицы сначала ищется в форме модуля, потом в общих таблицах. Если такой таблицы нет, то переданное имя будет рассматриваться как имя файла, содержащего данную таблицу" ... Все равно не понимаю, ведь и в том и в том случае Сформировать() по-идее должна запускаться в контексте report.ert, однако если мы запускаем ее из операторов в конце модуля, то на исполняется как бы от call_report.ert, а если из ПриОткрытии(), то в контексте report.ert. Фича наверное ;)
|
|||
14
Shaman100M
10.03.06
✎
14:55
|
(13) я уже не предполагаю, что - где, а принял за правило - "свободных операторов" не писать вообще.
|
|||
15
Вильям
10.03.06
✎
14:57
|
Использовать "код после всех процедур" - не очень хорошо с точки зрения хорошего стиля программирования. Не факт, что программу писать будете только Вы. Лучше, имхо, такие куски запихивать все же в ПриОткрытии(). Разбираться будет проще...
|
|||
16
twilight5023
10.03.06
✎
14:58
|
(14),(15) Да все вообщем-то правильно, просто до этого момента думал что между "свободными операторами" и ПриОткрытии() разница только в порядке исполнения. А оказывается еще и на контекст исполнения влияет. Теперь будем знать.
|
|||
17
GrayT
10.03.06
✎
14:59
|
Что то у меня не получилось смоделировать ситуацию. Нашел таблицу согласно 13
Движок какой? |
|||
18
twilight5023
10.03.06
✎
15:00
|
20-й, SQL.
|
|||
19
twilight5023
10.03.06
✎
15:01
|
(17) Сейчас допишу, ради интереса на 25-м попробую...
|
|||
20
twilight5023
10.03.06
✎
15:26
|
(17) На 25-м то же самое, смотри как проще смоделировать... делаем две обработки, r1.ert в ней таблицу с именем r1, текст модуля:
//******************************************* Процедура Сформировать() Таб = СоздатьОбъект("Таблица"); Таб.ИсходнаяТаблица("r1"); Таб.Показать(); КонецПроцедуры гПараметрыВызова = Форма.Параметр; Автозапуск = гПараметрыВызова.Получить("Автозапуск"); Если ПустоеЗначение(Автозапуск)=0 Тогда Если Автозапуск = 1 Тогда Сформировать(); Форма.Закрыть(0); КонецЕсли; КонецЕсли; И файл r2.ert: СписокПараметров = СоздатьОбъект("СписокЗначений"); СписокПараметров.ДобавитьЗначение(1, "Автозапуск"); ОткрытьФорму("Отчет",СписокПараметров,"r1.ert"); Таблицу r1 он не найдет. |
|||
21
twilight5023
10.03.06
✎
15:28
|
+20: Однако если запихнуть код после процедур (r1.ert) в ПриОткрытии(), то все заработает.
|
|||
22
GrayT
10.03.06
✎
15:48
|
Хм, действительно.
Причем для встроенных в конфу отчета, такого не наблюдается. Видимо проблема с тем, что пока проходит инициализация Таб. как объекта еще не существует :( |
|||
23
twilight5023
10.03.06
✎
15:51
|
(22) В смысле "как объекта не существует"? Если ты сделаешь таблицу с именем "r1" в модуле r2.ert, то он ее оттуда и покажет. Здесь какой-то баг с контекстом исполнения.
|
|||
24
twilight5023
10.03.06
✎
15:53
|
+23: Согласно определению в (13) он ищет таблицу "программном модуле которой запущена данная процедура", только вот почему-то он считает что запуск произошел из r2.
|
|||
25
GrayT
10.03.06
✎
16:01
|
(23)Согласен, я даже попытался с контекстом поиграться - ни чего путного не получилось.
|
|||
26
twilight5023
10.03.06
✎
16:04
|
(25) Может это в 1С или в базу знаний?
|
|||
27
АЛьФ
модератор
10.03.06
✎
16:04
|
Могу объяснить подобное поведение на уровне движка. Интересует?
|
|||
28
GrayT
10.03.06
✎
16:05
|
(27)Да
|
|||
29
twilight5023
10.03.06
✎
16:05
|
(27) Конечно.
|
|||
30
АЛьФ
модератор
10.03.06
✎
16:23
|
Делов том, что открытие встроенной формы и внешней обработки реализовано разными функциями внутри движка. При этом для того, чтобы модуль воспринимал таблицы-шаблоны в нужном контексте необходим вызов метода "void CGetDoc7::SetTableSourceForms(class CWorkBookDoc *,unsigned int)".
Далее. Вызов на исполнение операторов "тела" модуля происходит после компиляции методом "int CBLModule::Execute(void)", а предопределенный процедур далее после некоторой дополнительной инициализации. Суммируем и получаем. Для внешних обработок "SetTableSourceForms" вызывается после вызова "Execute", а для встроенных формы до. Соответственно если запускается открытие внешней обработки из другой внешней, то в момент исполнения "тела" модуля второй обработки "SetTableSourceForms" уже вызвана для первой, но еще не вызвана для текущей исполняемой и движок настроен на поиск таблиц в первой внешней. И, наконец, если открытие второй внешней идет из "тела" первой, то и для первой еще не вызвана "SetTableSourceForms" и поиск таблиц будет только в общих таблицах. Фух... Вроде так... |
|||
31
GrayT
14.03.06
✎
11:42
|
(30)Сенкс. К сожалению с Си не силен, но общую идею, кажись, понял. (22) было относительно верным предположением :)
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |