Сохранение в excel работает на клиенте, не работает на сервере

1. vechiy 35 15.07.21 22:54 Сейчас в теме
Печатная форма сохраняет ТабДок в эксель. Это работает, когда я открываю её через файл->открыть, и перестаёт работать, когда подключаю как внешнюю печатную форму в базу (erp).
Неправильно реализована серверная процедура Печать() ?

&НаКлиенте
Процедура Печать(Команда) Экспорт
	
	ТабДок = ПечатьНаСервере();
	
	ИмяПартнераДляФайла = стрзаменить(Строка(Объект.СсылкаНаОбъект)," ","");
	ИмяПартнераДляФайла = стрзаменить(ИмяПартнераДляФайла,".","");
	ИмяПартнераДляФайла = стрзаменить(ИмяПартнераДляФайла,"""","");
	ИмяФайла = сокрлп("Бланк_заказа_"+ИмяПартнераДляФайла+"_")+".xls";
	
	Режим = РежимДиалогаВыбораФайла.Сохранение; 
	ДиалогСохраненияФайла = Новый ДиалогВыбораФайла(Режим); 
	ДиалогСохраненияФайла.ПолноеИмяФайла = ИмяФайла; 
	Фильтр = "Excel(*.xls)|*.xls";                 
	ДиалогСохраненияФайла.Фильтр = Фильтр; 
	ДиалогСохраненияФайла.МножественныйВыбор = Ложь; 
	ДиалогСохраненияФайла.Заголовок = "Выберите файл"; 
	Если ДиалогСохраненияФайла.Выбрать() Тогда 
		ПутьКФайлу = ДиалогСохраненияФайла.ПолноеИмяФайла; 
	КонецЕсли;   

		
		Попытка
			ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLS);
			Сообщить("Файл записан: " + ПутьКФайлу);
		Исключение
			
			сообщить("При сохранении файла произошла ошибка");
			
		КонецПопытки;
		


	#Область ФормированиеExcel

    Эксель = Новый COMОбъект("Excel.Application");
    Эксель.Application.DisplayAlerts = False;
    Эксель.Application.ReferenceStyle = "xlR1C1";
    Эксель.Application.ErrorCheckingOptions.InconsistentFormula = Ложь;
	
    //Книга = Эксель.WorkBooks.Add();
	
    Книга = Эксель.Workbooks.Open(ПутьКФайлу);
    
    Лист = Книга.WorkSheets(1);
	
    
    ВсегоКолонок      = ТабДок.ШиринаТаблицы;
    ВсегоСтрок        = ТабДок.ВысотаТаблицы;
    
    МассивКом = Лист.Range(Лист.Cells(1, 1), Лист.Cells(ВсегоСтрок, ВсегоКолонок)).FormulaR1C1;
    Для Ном = 1 По МассивКом.GetLength(0) Цикл
        Для Ном2 = 1 По МассивКом.GetLength(1) Цикл
            Значение = МассивКом.GetValue(Ном,Ном2);
            
            Если НЕ Найти(Значение, "") = 0 Тогда
                МассивКом.SetValue(Ном, Ном2, СтрЗаменить(Значение, "", ""));
            КонецЕсли;
            
            Если СтрНачинаетсяС(Значение, "=") Тогда //Формулам зададим формат...
                Ячейка = Лист.Cells(Ном2,Ном);
                Ячейка.NumberFormat = "# ##0,00;-# ##0,00;""""";
            КонецЕсли;
            
        КонецЦикла;
    КонецЦикла;
    Лист.Range(Лист.Cells(1, 1), Лист.Cells(ВсегоСтрок, ВсегоКолонок)).FormulaR1C1 = МассивКом; //Если тут ошибка, то скорее всего косяк в формуле
    
    Книга.SaveAs(ПутьКФайлу);
    
    Эксель.Quit();
    Эксель = Неопределено;    
	
	#КонецОбласти
	
КонецПроцедуры

&НаСервере
Функция  ПечатьНаСервере()

	ТекОбъект = РеквизитФормыВЗначение("Объект");
	МассивОбъектов = Новый Массив;
	МассивОбъектов.Добавить(ТекОбъект.СсылкаНаОбъект);
	ОбъектыПечати =Новый СписокЗначений;
    ОбъектыПечати.ЗагрузитьЗначения(МассивОбъектов);
	ТабДок = ТекОбъект.ПечатьДокумента(МассивОбъектов,ОбъектыПечати);
	Возврат ТабДок;
	
КонецФункции
Показать
Прикрепленные файлы:
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
10. dj_tol 104 22.07.21 09:16 Сейчас в теме
(1)Вот еще можно воспользоваться Табличным документом: Прочитать и Записать. Тогда Excel не нужен.
11. user856012 14 22.07.21 09:45 Сейчас в теме
(10)
Вот еще можно воспользоваться Табличным документом: Прочитать и Записать.
Автор его уже использует, смотрите внимательнее. Но у него в ячейках формулы: https://forum.infostart.ru/forum9/topic265378/

Знаете способ записать такой файл без Excel?
2. coollerinc 196 15.07.21 23:36 Сейчас в теме
Так у вас ошибка, слишком много фактических параметров, у вас у процедуры Печать один параметр(команда), а в процедуре вызова два параметра.

У вас в клиентскую процедуру печать должны входить два параметра Идентификатор печати и объекты назначения. Вы должны брать документы для печати из второго параметра Объекты Назначения.
3. uno-c 265 16.07.21 00:06 Сейчас в теме
1) &НаКлиенте Печать(Команда) - это сейчас для кнопки(команды), ее отвязать от команды. Для команды сделать другую процедуру.
2) Переделать под БСП процедуру Печать(...)

&НаКлиенте
Процедура Печать(ИдентификаторКоманды, ОбъектыНазначенияМассив) Экспорт
   Объект.СсылкаНаОбъект = ОбъектыНазначенияМассив[0];
    // далее как было
   ТабДок = ПечатьНаСервере();
   // и т.д.
   ...
КонецПроцедуры
4. dj_tol 104 16.07.21 04:28 Сейчас в теме
Проблема в том, что Печать(Команда) - это кнопка на форме (с командой), а вам нужно
В модуле обработки


функция СведенияОВнешнейОбработке() Экспорт
	ПараметрыРегистрации = Новый Структура;
	МассивНазначений = Новый Массив;
	МассивНазначений.Добавить("Документ.БЛАБЛАБЛА"); //Указываем документ к которому делаем внешнюю печ. форму
	ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма"); //может быть - ПечатнаяФорма, ЗаполнениеОбъекта, ДополнительныйОтчет, СозданиеСвязанныхОбъектов... 
	ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
	ПараметрыРегистрации.Вставить("Наименование", "Коммерческое предложение внешняя"); //имя под которым обработка будет зарегестрирована в справочнике внешних обработок
	ПараметрыРегистрации.Вставить("БезопасныйРежим", ЛОЖЬ);
	ПараметрыРегистрации.Вставить("Версия", "1.1"); 
	ПараметрыРегистрации.Вставить("Информация", "БЛАБЛАБЛА."); 
	ТаблицаКоманд = ПолучитьТаблицуКоманд();
	ДобавитьКоманду(ТаблицаКоманд, "Коммерческое предложение", "КоммерческоеПредложение", "ВызовСерверногоМетода", Истина, "ПечатьMXL");
	ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
	
	Возврат ПараметрыРегистрации;	
КонецФункции	

Функция ПолучитьТаблицуКоманд()
	Команды = Новый ТаблицаЗначений;
	Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));//как будет выглядеть описание печ.формы для пользователя
	Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка")); //имя макета печ.формы
	Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка")); //ВызовСерверногоМетода
	Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
	Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
	Возврат Команды;
КонецФункции

Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
	
	НоваяКоманда = ТаблицаКоманд.Добавить();
	НоваяКоманда.Представление = Представление; 
	НоваяКоманда.Идентификатор = Идентификатор;
	НоваяКоманда.Использование = Использование;
	НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
	НоваяКоманда.Модификатор = Модификатор;
	
КонецПроцедуры

Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт

		УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
		КоллекцияПечатныхФорм,
		"КоммерческоеПредложение",
		ВернутьЗаголовок(МассивОбъектов),
		ТабличныйДокументКоммерческоеПредложение( МассивОбъектов, ОбъектыПечати),
		,
		"КоммерческоеПредложение");


КонецПроцедуры // Печать()

#Область СлужебныеПроцедурыИФункции

// Процедура печати документа.
// Возвращает табличный документ - сформированную печатную форму расчета оплаты пособия.
//
// Параметры:
//	МассивОбъектов - массив сотрудников.
//  ОбъектыПечати  - Список значений  - Объекты печати (значение - ссылка на объект, представление - имя области в
//                   которой был выведен объект).
//
// Возвращаемое значение:
//	Табличный документ
//
Функция ТабличныйДокументКоммерческоеПредложение( МассивОбъектов, ОбъектыПечати)Экспорт
	
	ТабДок = Новый ТабличныйДокумент;
	ТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
	ТабДок.АвтоМасштаб = Истина;
	ТабДок.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_ЛИЗ_КОММЕРЧЕСКОЕ_ПРЕДЛОЖЕНИЕ";
	
	УстановитьПривилегированныйРежим(Истина);
	
	Макет = ПолучитьМакет("КоммерческоеПредложение");
	
	ВывестиДанныеКоммерческогоПредложенияВТабличныйДокумент(Макет, ТабДок, МассивОбъектов, ОбъектыПечати);
	
	УстановитьПривилегированныйРежим(Ложь);
	
	Возврат ТабДок;
	
КонецФункции


Процедура ВывестиДанныеКоммерческогоПредложенияВТабличныйДокумент(Макет, ТабличныйДокумент, объект,  ОбъектыПечати)


//Вот тут вы и выводите свое чудо


КонецПроцедуры
#КонецОбласти
Показать
5. dj_tol 104 16.07.21 04:29 Сейчас в теме
6. uno-c 265 16.07.21 08:37 Сейчас в теме
(5)
//Вот тут вы и выводите свое чудо
Проблема в том, что на сервере нет Excel. Поэтому Ваш вариант из модуля обработки выдаст ошибку, когда попробует выполнить в частности вот такое чудо
Эксель = Новый COMОбъект("Excel.Application");
Автору вопроса нужен клиентский вариант. Поскольку с подключением дополнительной обработки проблем не возникло и, судя по ошибке, из БСП уже идет вызов клиентской экспортной процедуры Печать() - значит СведенияОВнешнейОбработке() уже написаны и свое отрабатывают, их пока не нужно трогать.

Пока достаточно поправить параметры клиентской процедуры Печать() и дописать одну строчку, как я указал в (3)
7. vechiy 35 16.07.21 16:33 Сейчас в теме
текущий вопрос частично был снят, но есть другой: возможно ли при таком сохранении в эксель защитить часть листа книги от редактирования (доступными оставить список ячеек)?
8. uno-c 265 16.07.21 20:15 Сейчас в теме
(7) Частично - это как? Ошибка осталась ?
9. Xershi 1553 19.07.21 23:13 Сейчас в теме
(7) читайте возможности эксель. Если интересно возможно, то по идее да.
12. PeRom 51 25.07.21 19:12 Сейчас в теме
(7)Возможно всё что делаешь и в екселе, сделать и из 1с - задать снять пароли, внести формулы, защитить\снять защиту и тп, главное подобрать нужную команду екселя. Какие есть команды всегда смотрел в МСДН(на аглицком, понятное дело).
13. uno-c 265 29.07.21 01:07 Сейчас в теме
(12) А еще можно распаковать XLSX архив, внести требуемые изменения в xml-файлы, из которых он состоит, и снова их запаковать в XLSX - тогда даже COM-Excel не нужен.
14. hamsar 16 22.08.21 09:24 Сейчас в теме
Сам Эксель на сервере ещё должен стоять, читать данные в ТЧ передавать
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот