Имя: Пароль:
1C
1С v8
Передача сервера на клиент ТЗ для выгрузки в шаблон.
0 lirt82
 
06.05.26
10:10
На форме типового документа в ЕРП, добавил команду через расширение, суть необходимо выгрузить таб часть Товары документа в файл эксель. Получаю таб часть Товары, обрабатываю и выгружаю в ТЗ и передаю с сервера на клиент (в команду) при получении на клиенте выходит ошибка, подскажите как исправить?
******
&НаКлиенте
Процедура ВыгрузитьВExcel(Команда)

    Попытка
        Excel = Новый COMОбъект("Excel.Application");
        Excel.WorkBooks.Open(Шаблон);
        Состояние("Открытие файла Microsoft Excel...");
    Исключение
        Сообщить("Ошибка при открытии файла " + Символы.ПС + ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    Состояние("Выгрузка...", , , БиблиотекаКартинок.ДлительнаяОперация48);  
    
    Попытка
        АдресТЗ_ДляВыгрузки = ОбработатьТабЧастьДокументаНаСервере();
        ТаблицаДляВыгрузки = ПолучитьИзВременногоХранилища(АдресТЗ_ДляВыгрузки);  
    Исключение
        Сообщить("Произошла ошибка при получении данных: " + ОписаниеОшибки());
        Excel.Workbooks.Application.DisplayAlerts = Ложь;
        Excel.Quit();
        Excel = 0;
        Возврат;
    КонецПопытки;
***********************
&НаСервере
Функция ОбработатьТабЧастьДокументаНаСервере()
    
    ТаблицаЗначенийТовары = Источник.Товары.Выгрузить(, "Номенклатура, КоличествоУпаковок, СтатьяРасходов");
    ТаблицаЗначенийТовары.Свернуть("Номенклатура, СтатьяРасходов", "КоличествоУпаковок");
    
    ТЗ_ДляВыгрузки = Новый ТаблицаЗначений;
    ТЗ_ДляВыгрузки.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(100)));
    ТЗ_ДляВыгрузки.Колонки.Добавить("Код",          Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(11)));
    ТЗ_ДляВыгрузки.Колонки.Добавить("Количество",   Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));
    ТЗ_ДляВыгрузки.Колонки.Добавить("СтатьяЗатрат", Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(100)));
    
    Для Каждого СтрокаТЗ_Товары Из ТаблицаЗначенийТовары Цикл
        НоваяСтрокаТЗ_ДляВыгрузки              = ТЗ_ДляВыгрузки.Добавить();
        НоваяСтрокаТЗ_ДляВыгрузки.Номенклатура = СокрЛП(СтрокаТЗ_Товары.Номенклатура.Наименование);
        НоваяСтрокаТЗ_ДляВыгрузки.Код          = СокрЛП(СтрокаТЗ_Товары.Номенклатура.Код);
        НоваяСтрокаТЗ_ДляВыгрузки.Количество   = Строка(СтрокаТЗ_Товары.КоличествоУпаковок);
        НоваяСтрокаТЗ_ДляВыгрузки.СтатьяЗатрат = СокрЛП(СтрокаТЗ_Товары.СтатьяРасходов.Наименование);
    КонецЦикла;
    
    АдресВХранилище = ПоместитьВоВременноеХранилище(ТЗ_ДляВыгрузки, ЭтаФорма.УникальныйИдентификатор);
    
    Возврат АдресВХранилище;
    
КонецФункции
**********************
https://ibb.co.com/LzTZxWWh
https://ibb.co.com/Qj1HRz2v
1 АЛьФ
 
06.05.26
10:26
Не передавать с сервера на клиент ТЗ. Делать все на сервере, а на клиента передавать готовый файл.
2 Мультук
 
гуру
06.05.26
10:37
(0)
Если сильно надо на клиенте, то
засунуть таблицу значений в массив структур и возвращать его.

ОбщегоНазначения.ТаблицаЗначенийВМассив
3 X Leshiy
 
06.05.26
10:48
Жертвы ИИ)
4 X Leshiy
 
06.05.26
10:52
Вы
10:46:25
как передать таблицу значений с сервера на клиент?
ИИ
10:46:25
Таблица значений может передаваться с сервера на клиент как сериализуемый тип данных. Вот основные способы:

1. Возврат из серверной функции
// Сервер
&НаСервереБезКонтекста
Функция ПолучитьТаблицуДанных()
    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Наименование");
    Таблица.Колонки.Добавить("Количество");
    Строка = Таблица.Добавить();
    Строка.Наименование = "Товар 1";
    Строка.Количество = 10;
    Возврат Таблица;
КонецФункции
// Клиент
&НаКлиенте
Процедура ЗагрузитьТаблицу()
    ТаблицаНаКлиенте = ПолучитьТаблицуДанных();
КонецПроцедуры
КопироватьКопировать
2. Через реквизит формы
Создайте реквизит формы с типом ТаблицаЗначений и заполняйте его на сервере.

3. Через временное хранилище (для больших данных)
// Сервер
Адрес = ПоместитьВоВременноеХранилище(Таблица);
// Клиент
Таблица = ПолучитьИзВременногоХранилища(Адрес);
КопироватьКопировать
Код валиден. Таблица значений - сериализуемый тип, поэтому напрямую передается между сервером и клиентом. Для больших объемов данных используйте временное хранилище.

Вы
10:48:31
Ты забыл, что таблица значений не сериализуется?
ИИ
10:48:31
Вы правы, ошибся. Таблица значений не сериализуется и не может быть передана напрямую с сервера на клиент.
Правильные способы:

1. Через Массив структур
// Сервер
&НаСервереБезКонтекста
Функция ПолучитьДанные()
    МассивДанных = Новый Массив;
    // Преобразуем ТаблицаЗначений в массив структур
    Для Каждого СтрокаТаблицы Из ИсходнаяТаблица Цикл
        Структура = Новый Структура("Наименование,Количество");
        Структура.Наименование = СтрокаТаблицы.Наименование;
        Структура.Количество = СтрокаТаблицы.Количество;
        МассивДанных.Добавить(Структура);
    КонецЦикла;
    Возврат МассивДанных;
КонецФункции
КопироватьКопировать
2. Через Таблицу формы
// Сервер
&НаСервере
Процедура ЗаполнитьТаблицуНаСервере()
    Элементы.ТаблицаФормы.Загрузить(ИсходнаяТаблица);
КонецПроцедуры
КопироватьКопировать
3. Через временное хранилище
// Сервер
Адрес = ПоместитьВоВременноеХранилище(Таблица);
// Клиент
Таблица = ПолучитьИзВременногоХранилища(Адрес);
КопироватьКопировать
Код валиден. Для передачи табличных данных используйте сериализуемые типы: Массив структур, СписокЗначений или Таблицу формы.

Вы
10:49:40
А через временное хранилище ТОЧНО можно передать таблицу значений?
ИИ
10:49:40
Проверю документацию по временному хранилищу и сериализации ТаблицыЗначений.
Вы правы, есть нюанс. Таблица значений сериализуется (в XDTO), но имеет доступность: Сервер, толстый клиент, внешнее соединение - НЕ доступна на тонком/веб-клиенте.
Поэтому для передачи на тонкий клиент нужно использовать обходные пути:

Вариант 1: Через ХранилищеЗначений + временное хранилище
// Сервер
&НаСервереБезКонтекста
Функция ПередатьТаблицуВХранилище()
    Хранилище = Новый ХранилищеЗначения(Таблица);
    Адрес = ПоместитьВоВременноеХранилище(Хранилище, УникальныйИдентификатор);
    Возврат Адрес;
КонецФункции
// Клиент (толстый клиент)
&НаКлиенте
Процедура ПолучитьТаблицу()
    Хранилище = ПолучитьИзВременногоХранилища(Адрес);
    Таблица = Хранилище.Получить();
КонецПроцедуры
КопироватьКопировать
Для тонкого/веб-клиента используйте Массив структур (как в предыдущем ответе) или ДанныеФормыКоллекция.
Код валиден. Резюме:

Тонкий/веб-клиент: используйте Массив структур
Толстый клиент: можно использовать ХранилищеЗначений + временное хранилище
5 X Leshiy
 
06.05.26
10:54
Только с 3 раза более менее правильно ответил)
6 Timon1405
 
06.05.26
10:55
Если решил ты в расширение
Кнопку важную создать,
Чтобы «Товары» из программы
В файл Excel перегружать,

Не читай документацию —
Это чтиво для зануд.
выгружай в ТЗ всё сразу,
Пусть на сервере живут.

А потом ТЗ в охапку —
И на клиент её тащи!
Если выскочит ошибка —
В монитор сильней кричи.

Пусть «Мутабельное значенье»
Твой компьютер прохрипит,
Ты не вздумай в Структуру
Данные переложить!

Не используй Массив строк,
И в ДанныеФормы не пихай,
Просто серверную таблицу
Прямо в морду клиенту дай!

Если 1С ругается,
Что не знает тип такой,
Бей по клавишам сильнее —
Сразу будешь ты крутой!
7 X Leshiy
 
06.05.26
11:00
(6)  Агонь)
8 lirt82
 
06.05.26
11:03
(4) ТаблицаДляВыгрузки = ПолучитьИзВременногоХранилища(АдресТЗ_ДляВыгрузки);  
у меня здесь ошибка
9 Timon1405
 
06.05.26
11:06
(0) ну если серьезно, то прям ком объектом эксель нужен обычно только в редких случаях, когда нужна выгрузка с хитрыми формулами или условным оформлением.

как именно звучит исходная задача, что она не решается через ВПФ с табдоком и его интерактивным сохранением в эксель?
10 lirt82
 
06.05.26
11:09
(9) необходимо выгрузить таб часть Товары документа Внутреннее потребление в строгий шаблон файла Excel.
11 Timon1405
 
06.05.26
11:20
(10) и что же в нем строгого чего нельзя сделать макетом?
12 Timon1405
 
06.05.26
11:23
(10) см УстановкаЦенКлиент.ВыгрузитьВExcel(
13 vis
 
06.05.26
11:31
(10) Нужно заполнить именно существующий Excel файл?
Или надо создать Excel файл нужной структуры?
Основная теорема систематики: Новые системы плодят новые проблемы.