Есть модуль формы,н-р, документа, в нем на клиенте процедура, в которой нужно рассчитать данные.
1.Если из этой клиентской процедуры - вызывать рассчетную функцию/проц прямо из этого модуля формы под сервером - то работает,
2.Если из этой клиентской процедуры - вызывать рассчетную функцию/проц из модуля данного объекта - работает,
3.А если рассчетную функцию/проц вынести в ОбщиеМодули,то никак не работает!!!....уже что только не делала с настройками ОбщегоМодуля - ничего не работает!!!
// Может использоваться для передачи на клиента данных, полученных
// на сервере в виде таблицы значений в том случае, если таблица
// значений содержит только такие значения, которые могут
// быть переданы на клиента.
//
// Полученный массив содержит структуры, каждая из которых повторяет
// структуру колонок таблицы значений.
//
// Не рекомендуется использовать для преобразования таблиц значений
// с большим количеством строк.
//
// Параметры:
// ТаблицаЗначений - ТаблицаЗначений
//
// Возвращаемое значение:
// Массив
//
Функция ТаблицаЗначенийВМассив(ТаблицаЗначений) Экспорт
Массив = Новый Массив();
СтруктураСтрокой = "";
НужнаЗапятая = Ложь;
Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
Если НужнаЗапятая Тогда
СтруктураСтрокой = СтруктураСтрокой + ",";
КонецЕсли;
СтруктураСтрокой = СтруктураСтрокой + Колонка.Имя;
НужнаЗапятая = Истина;
КонецЦикла;
Для Каждого Строка Из ТаблицаЗначений Цикл
НоваяСтрока = Новый Структура(СтруктураСтрокой);
ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);
Массив.Добавить(НоваяСтрока);
КонецЦикла;
Возврат Массив;
КонецФункции
Формы обычные или управляемые?
Если управляемые, то не понимаю как у тебя работает из клиентской процедуры вызов функции модуля объекта.
Если обычные, то не понимаю что такое "под клиентом", "под сервером". Там все под клиентом.
Ну, показывай, как у тебя в УФ работает вызов с клиента функции модуля объекта. Интересно посмотреть на такое чудо.
И запомни, фразу "ничего не работает" могут позволить себе только пользователи. Программисты говорят - "на такой-то строке кода выдает такую-то ошибку".
Итак,все по порядку:
1.В модуле формы документа под кнопкой у меня есть процедура на клиенте:
&НаКлиенте
Процедура КонтактыКлиента(Команда)
Структура=Новый Структура("Партнеры,Контрагенты",Объект.Партнер,Объект.Контрагент);
///вызываю рассчетную проц.,из-за которой и есть данный вопрос
КонтактыКлиентаНаСервере(Структура,ТаблицаЗапр);
//здесь просто вызов модальной формы отчета
УсловияОтбора=Новый Структура("Партнеры,Контрагенты,Договор,ДатаДоговора,СсылкаДоговора",
Объект.Партнер,Объект.Контрагент,Объект.Номер,Объект.Дата,Объект.Ссылка);
ПараметрыФормы = Новый Структура("Отбор, СформироватьПриОткрытии", УсловияОтбора, Истина);
ОткрытьФорму("Отчет.КонтактыКлиентов.ФормаОбъекта", ПараметрыФормы);
КонецПроцедуры
Показать
2.В данном же модуле формы документа,только на сервере создаю эту рассчетную проц.
&НаСервере
Процедура СоздатьТабКонтактыКлиента(ТаблицаЗапр)
Контрагенты=Объект.Контрагент;
Партнеры=Объект.Партнер;
ВнешниеДанные=Новый ТаблицаЗначений;
ВнешниеДанные.Колонки.Добавить("Партнеры",Новый ОписаниеТипов("СправочникСсылка.Партнеры"));
ВнешниеДанные.Колонки.Добавить("Контрагенты",Новый ОписаниеТипов("СправочникСсылка.Контрагенты"));
стр=ВнешниеДанные.Добавить();
стр.Контрагенты=Контрагенты;
стр.Партнеры=Партнеры;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВнешниеДанные.Контрагенты,
| ВнешниеДанные.Партнеры
|ПОМЕСТИТЬ ВнешниеДанные
|ИЗ
| &ВнешниеДанные КАК ВнешниеДанные
|;
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| КонтрагентыКонтактнаяИнформация.Представление КАК ВидКонтактов,
| КонтрагентыКонтактнаяИнформация.Вид.Наименование КАК Контакты
|ИЗ
| ВнешниеДанные КАК ВнешниеДанные
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты.КонтактнаяИнформация КАК КонтрагентыКонтактнаяИнформация
| ПО ВнешниеДанные.Контрагенты = КонтрагентыКонтактнаяИнформация.Ссылка
|ОБЪЕДИНИТЬ
|ВЫБРАТЬ
| ПартнерыКонтактнаяИнформация.Представление,
| ПартнерыКонтактнаяИнформация.Вид.Наименование
|ИЗ
| ВнешниеДанные КАК ВнешниеДанные
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Партнеры.КонтактнаяИнформация КАК ПартнерыКонтактнаяИнформация
| ПО ВнешниеДанные.Партнеры = ПартнерыКонтактнаяИнформация.Ссылка";
Запрос.УстановитьПараметр("ВнешниеДанные",ВнешниеДанные);
РезультатЗапроса = Запрос.Выполнить();
ТаблицаЗапр=РезультатЗапроса.Выгрузить();
//Для каждого СтрокаТаблицы Из ТаблицаЗапр Цикл
// Сообщить("" + СтрокаТаблицы.ВидКонтактов+СтрокаТаблицы.Контакты);
//КонецЦикла;
КонецПроцедуры
Показать
3.в таком варианте (что пункт2) - работает, теперь я могу рассчетную проц.запихнуть в МодульДокумента, и вызвать ее оттуда.Для этого я в первой проц буду ссылаться не на саму рассчетную проц., а лишь через ссылку сервера, естественно,что рассчетную проц,к-я уже в МодулеДока я обозвала немного иначе "КонтактыКлиентаНаСервереМодуль"
4.так тоже работает. Но мне очень хотелось затолкать рассчетную процедуру в ОбщийМодуль,чтобы ее можно было вызывать откуда угодно....Ничего не вышло - не работает
1. Находясь в клиентской процедуре в модуле формы - я могу здесь же(в модуле формы) вызвать серверную проц.расчета и все работает, но почему если я отсюда (с клиентской проц.в модуле формы) буду вызывать ту же серверную проц. но из ОбщегоМодуля,то не работает???
2.Хорошо,из клиентской проц в модуле формы вызываю здесь же серверную проц., и уже через нее пытаюсь вызвать серверную рассчетную проц. из ОбщегоМодуля - не работает...
3.Ладно, делаю еще ход конем: из клиентской проц.модуля формы - ссылаюсь на северную проц.модуля формы, в ней передаю параметры объекта и таким образом вызываю еще одну проц.северную,которая в МодулеОбъекта формы - и вот отсюда я вновь пробую вызвать рассчетную проц.северную из ОбщегоМодуля - не работает!!!
Не работает, не получается, не выходит, не удаётся...
Поэтому и спрашиваю...
Ошибку система выдает как "Переменная не определена - ОбщийМодульКонтакты" (см.рис.)....
И почему система название Общего модуля видит как переменная - тоже не понятно...
п.с. на всякий случай, сбрасываю сюда свой черновик, сейчас там настроен - вызов глобальной процедуры ОбщийМодульКонтакты.КонтактыКлиентаНаСервереМодульОбщий(Структура,ТаблицаЗапр) из северной проц.в модуле формы документа "ДоговорСтроительноМонтажныхРабот"
Может кто разберется, да подскажет в чем секрет "галок" и директив???
(17)это я тоже проверяла - перегоняла только структруру - тот же результат...
п.с.Но в текущем варианте подключения - вызывает именно серверная проц.модуля формы .- серверную проц.ОбщегоМодуля , то есть сервер сервер опрашивает...
Вновь везде перегнала структура, а в ОбщемМодуле - поставила не Процедура, а Функция с возвратом на клиентскую проц. в модуль формы Таблицы - и заработало!!!
Спасибо!!!!!!!!!!!!!!!
п.с. Добавлю сюда базу-черновик,где все работает!!! памятка будет))
В принципе, механизм запроса серверной процедуры модуля формы документа в ОбщийМодуль серверной функции - работает: просто в параметрах передаю структуру,а обратно из функции получаю таблицу значений.
Но вот внимательно продолжаю читать книгу Хрусталева/Радченко "Практическое пособие разработчика 8.3" стр.206,где четко написано:
"При вызове процедуры или функции ее поиск осуществляется сначала на клиенте. Если скомпилированный контекст клиента не содержит данную процедуру,то поиск продолжается на стороне сервера. Если вызываемая процедура будет найдена,то выполнение кода будет передано на сервер.После завершения процедуры выполнение кода продолжится на клиенте"
Теперь напомню рабочий вариант приведенного в этой ветке примера: в модуле формы на клиентской процедуре -
1. мы сначала переходим в серверную процедуру этой же команды в этом же модуле формы,
2.далее из серверной команды в модуле формы - мы вызываем серверную функцию из Общего Модуля.
А вот теперь вопрос - а почему нельзя сразу из клиентской процедуры модуля формы - вызвать серверную функцию ОбщегоМодуля?????
Ведь,в книге явно сказано,что это возможно!!!!
Проверяю данный вариант - пробую из клиентской проц.в модуле формы вызвать сразу северную ф-цию ОбщегоМодуля,см.рис1,то при проверке в пользоват.режиме - выскочит сл.ошибка "Метод объекта не обнаружен"!!!
Почему так не работает???? В чем разница-то???
Ведь при первом варианте - мы вызываем из клиента на форме - сервер на форме - и снего вызываем сервер ОбщегоМодуля,а потом обратно все результаты отправляем на КЛИЕНТА формы,где идет сл.выполнение кода!!!!
в общМодуле - исполнение на сервере,т.к.там создается таблицаЗначений!!!!
Если у общего модуля отключу галку -на сервере,то будет ошибка из предыдущ.скрина,
если удалю директиву на сервере или заменю на клиенте - не определяются таб.знач!
п.с.а простой массив - можно результатом функции передать в клиентскую проц???
если простой массив,то сейчас попробую, а что такое Массив структур - я не знаю...
то точно знаю,что в нем две колонки с именами,переданными запросом:"ВидКонтактов","Контакты", то есть это все равно,что двумерный массив...
Сейчас подумаю как заполнить именно двумерный массив, а потом как его расшифровать в принимающей проц.подумаю...
п.с.А из Вашего примера не разберусь: КАК запихать эти колонки в такой вид Массива со структурой и потом его еще расшифровать в принимающей проц - что-то не соображу никак....
Получилось!!! Это тоже самое,что и двумерный массив,но считывать можно по точке!!!
В конец рассчетной серверной ф-ции в Общем модуле ставлю код:
Массив = Новый Массив;
Для каждого СтрокаТаб Из ТаблицаЗапр Цикл
Массив.Добавить(Новый Структура("ВидКонтактов, Контакты", СтрокаТаб.ВидКонтактов, СтрокаТаб.Контакты)) ;
КонецЦикла;
Возврат Массив;
А в вызывающей/принимающей клиентской проц ставлю сл.считыватель такого Массива Структур:
Для каждого СтрокаМассива Из МассивЗнач Цикл
Сообщить("" + СтрокаМассива.ВидКонтактов+СтрокаМассива.Контакты);
КонецЦикла;
Итак, в конец рассчетной серверной функции в ОбщемМодуле добавляю преобразование данных из таблицы значений в двумерный массив:
Массив=Новый Массив(ТаблицаЗапр.Количество(),2);
н=0;
Для каждого СтрокаТаб Из ТаблицаЗапр Цикл
Массив[н][0]= СтрокаТаб.ВидКонтактов;
Массив[н][1]= СтрокаТаб.Контакты;
н=н+1;
КонецЦикла;
Возврат Массив;
Показать
А в принимающей клиентской процедуре - просто читаю данные из полученного с сервера двумерного Массива:
&НаКлиенте
Процедура КонтактыКлиента(Команда)
Структура=Новый Структура("Партнеры,Контрагенты",Объект.Партнер,Объект.Контрагент);
МассивЗнач=ОбщийМодульКонтакты.КонтактыКлиентаНаСервереМодульОбщий(Структура);
н=0;
Для каждого СтрокаМассива Из МассивЗнач Цикл
Сообщить("" + МассивЗнач[н][0]+МассивЗнач[н][1]);
н=н+1;
КонецЦикла;
КонецПроцедуры
Показать
Все работает!!!см.скрин
причем настройки Общего модуля=Сервер,ВызовСервера=Да,исполнение ф-ции в Общем модуле идет на сервере. Вызов рассчетной ф-ции идет с клиента, ответ получает все тот же клиент.
Отладка запускается под Тонким клиентом - все работает!
п.с. Но теперь очень хочу увидеть КАК тот же механизм можно запустить не двухмерным Массивом, а Массивом со структурой! Пожалуйста, напишите код!!!!!!!!!!!
// Может использоваться для передачи на клиента данных, полученных
// на сервере в виде таблицы значений в том случае, если таблица
// значений содержит только такие значения, которые могут
// быть переданы на клиента.
//
// Полученный массив содержит структуры, каждая из которых повторяет
// структуру колонок таблицы значений.
//
// Не рекомендуется использовать для преобразования таблиц значений
// с большим количеством строк.
//
// Параметры:
// ТаблицаЗначений - ТаблицаЗначений
//
// Возвращаемое значение:
// Массив
//
Функция ТаблицаЗначенийВМассив(ТаблицаЗначений) Экспорт
Массив = Новый Массив();
СтруктураСтрокой = "";
НужнаЗапятая = Ложь;
Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
Если НужнаЗапятая Тогда
СтруктураСтрокой = СтруктураСтрокой + ",";
КонецЕсли;
СтруктураСтрокой = СтруктураСтрокой + Колонка.Имя;
НужнаЗапятая = Истина;
КонецЦикла;
Для Каждого Строка Из ТаблицаЗначений Цикл
НоваяСтрока = Новый Структура(СтруктураСтрокой);
ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);
Массив.Добавить(НоваяСтрока);
КонецЦикла;
Возврат Массив;
КонецФункции
Функция ТаблицаЗначенийВМассив(ТаблицаЗначений) Экспорт
и так тоже работает,имя своей таблицы подставила:
Массив = Новый Массив();
СтруктураСтрокой = "";
НужнаЗапятая = Ложь;
Для Каждого Колонка Из ТаблицаЗапр.Колонки Цикл
Если НужнаЗапятая Тогда
СтруктураСтрокой = СтруктураСтрокой + ",";
КонецЕсли;
СтруктураСтрокой = СтруктураСтрокой + Колонка.Имя;
НужнаЗапятая = Истина;
КонецЦикла;
Для Каждого Строка Из ТаблицаЗапр Цикл
НоваяСтрока = Новый Структура(СтруктураСтрокой);
ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);
Массив.Добавить(НоваяСтрока);
КонецЦикла;
Возврат Массив;
Показать
п.с.этот кусочек кода вставить в конец рассчетной серверной ф-ции в ОбщемМодуле,в принимающей клиентской проц.расшифровка такого массива по точке:
Для каждого СтрокаМассива Из МассивЗнач Цикл
Сообщить("" + СтрокаМассива.ВидКонтактов+СтрокаМассива.Контакты);
КонецЦикла;
Все четко выполняется под Тонким Клиентом!!!Спасибо.
Вывод, в книге Радченко/Хрусталева - все правильно написано - можно передавать с клиента на сервер процедуры, и они возвращаются обратно на Клиент.
Важно только между клиентом и сервером перегонять в параметрах и в результатах или Структуру или Массив!!!
п.с. Остался совсем маленький уточняющий вопрос: а почему когда я передавала с серверной проц в модуле формы на серверную проц в Общем модуле в параметрах Структуру,а получала обратно в серверную проц.в модуле формы ТАБЛИЦУ значений и ее уже в параметрах серверной проц.из модуля формы отправляла в КЛИЕНТскую проц в модуле формы - то тоже все прекрасно работало??????????
Почему??? Почему что передача таблицы в параметрах между сервером и клиентом шла успешно в рамках ОДНОГО локального модуля на форме????
п.с.2 Если в рамках одного модуля можно передавать Таблицу значений между сервером и клиентом, то почему это нельзя в более крупных масштабах???
Если в рамках одного модуля можно передавать Таблицу значений между сервером и клиентом, то почему это нельзя в более крупных масштабах???
Вообще никак нельзя передать ТЗ с сервера на клиент, ибо на клиенте нет такого типа, как ТЗ. Если что-то работало, то где-то что-то кому-то померещилось. ТЗ на "клиенте" есть только в толстом клиенте, а тонком клиенте ТЗ на клиенте быть не может (если это, конечно, не таблица формы, которая имеет на клиенте и на сервере несколько иной тип, отличный от типа ТЗ).
Если что-то работало, то где-то что-то кому-то померещилось.
в моем сообщении (20) можете взять мою базу-черновик,открыть модуль формы документа "ДоговорСтроительноМонтажныхРабот" и посмотреть что работает!!!
Скины данного рабочего варианта в том же диапазоне постов есть - все работает.
Если Вы можете объяснить - ПОЧЕМУ это работает,то будет очень интересно.....
п.с.Я вот пока негде не встречала в обучающих книгах,что между клиентом и сервером нельзя передавать таблицы значений...Может еще пока не дочитала до этого места,покажите цитату тогда Вы,пожалуйста...
Таблица значений предназначена для хранения значений в табличном виде. Все основные операции с таблицей производятся именно через этот объект. Он позволяет манипулировать строками таблицы значений и предоставляет доступ к коллекции колонок. Колонки могут быть различных типов (в том числе множественных).
Доступность:
Сервер, толстый клиент, внешнее соединение, мобильное приложение(сервер).
Возможен обмен с сервером. Сериализуется. Данный объект может быть сериализован в/из XDTO. Тип XDTO, соответствующий данному объекту, определяется в пространстве имен {http://v8.1c.ru/8.1/data/core}. Имя типа XDTO: ValueTable.
Видите, что никакого "клиент" нет в списке доступности.
так расчет с таблицами у меня на сервере и идет - в ОбщемМодуле, но результат данной рассчетной ф-ции как ТАБЛИЦА значений - возвращается обратно и через сервер в модуле дока попадает по параметрам в клиент модуля того же дока и работает!!!
Поэтому - если внутри одного модуля - я могу через параметры передавать ТАБЛИЦУ значений между клиентом и сервером, почему я не могу этого сделать напрямую в сторонний модуль????
Приведу краткий пример КАК работает ТЗ на клиент-сервере в локальном модуле (это можно посмотреть в базе-черновике пост№ 20,но проще сюда привести данный код).
Итак,в модуле формы документа, в клиентской процедуре обращаемся в серверную процедуру того же модуля формы:
&НаКлиенте
Процедура КонтактыКлиента(Команда)
Перем ТаблицаЗапр;
Структура=Новый Структура("Партнеры,Контрагенты",Объект.Партнер,Объект.Контрагент);
КонтактыКлиентаНаСервере(Структура,ТаблицаЗапр);
Для каждого СтрокаТаблицы Из ТаблицаЗапр Цикл
Сообщить("" + СтрокаТаблицы.ВидКонтактов+СтрокаТаблицы.Контакты);
КонецЦикла;
Показать
В первом кодинге из клиентской проц.в модуле формы вызвали серверную проц.того же модуля=> КонтактыКлиентаНаСервере(Структура,ТаблицаЗапр);
Далее в этой серверной проц.в модуле формы мы вызываем серверную ф-цию из ОбщегоМодуля:
Здесь обратите внимание,что в рассчетную функцию,которая выполняется на сервере в Общем Модуле - в параметрах мы передаем СТРУКТУРУ, а вот обратно из рассчетной ф-ции мы получаем ТАБЛИЦУ значений=>ТаблицаЗапр=ОбщийМодульКонтакты.КонтактыКлиентаНаСервереМодульОбщий(Структура);
И уже полученную обратно в серверную проц.модуля формы Таблицу значений - мы передаем ее в виде параметра обратно в клиентскую процедуру этого же модуля!!!!
А уже на клиенте из полученной назад ТАБЛИЦЫ значений выводим данные на экран.
Для каждого СтрокаТаблицы Из ТаблицаЗапр Цикл
Сообщить("" + СтрокаТаблицы.ВидКонтактов+СтрокаТаблицы.Контакты);
КонецЦикла;
Это все на КЛИЕНТЕ,причем выводим на экран циклом коллекций значений.
Работает же! И клиент с сервера получает Талицу значений и перерабатывает ее в цикле и выводит на экран!
А почему??? Если "вообще ТЗ нельзя передавать между клиентом и сервером"?
(59)я только учусь...А здесь на форуме попалась интересная задачка с оптимизацией запроса - как раз та тема, над которой я билась в тот момент, но пока ее решила - появились по ходу события новые вопросы,вот и разбиралась в них...
Кроме директив и табЗначения у меня еще остался вопрос,отголосок эха той задачки, просто уже боюсь его задавать на форуме))...это про отчеты...