Документ Excel 2007 не может содержать более 16384 колонок и 1048576 строк. Ошибка при выгрузке пакетом

1. Redempty 04.12.23 06:44 Сейчас в теме
Здравствуйте. Подскажите, что делаю не так, вылазит ошибка: "Документ Excel 2007 не может содержать более 16384 колонок и 1048576 строк" при попытке выгрузки данных по нескольким организациям в Excel.

При этом с одной организацией все работает отлично хоть за год выгружает. В темах писали, что при смене контекста может истекать время жизни, но у меня уникальные идентификаторы присвоены при добавлении листов в соответствие.

Размеры точно не превышают эти листы, там в сумме выходит не больше 500х100.

Хочется научить правильно отрабатывать готовую версию обработки, чем с нуля писать новую на COM объектах. Не хватает какой-то маленькой детали

&НаКлиенте
Процедура СоздатьКнигу(Команда)
	Объект.СуммыПоСчетам.Очистить();
	ДанныеФайла = СоздатьКнигуНаСервере();
	Если ДанныеФайла <> Ложь Тогда
		СформироватьФайлПакетом(ДанныеФайла["Каталог"], ДанныеФайла["МассивЛистов"]);
	КонецЕсли;
КонецПроцедуры

&НаСервере
Функция СоздатьКнигуНаСервере()
	МассивЛистов = Новый Соответствие;
	
	ВысотаВсех = 0;
	ШиринаВсех = 0;
	Для каждого Организация из СписокОрганизаций Цикл
		БанковскиеСчетаПоОрганизации = БанковскиеСчета.НайтиСтроки(Новый Структура("Организация",Организация.Значение));
		Для каждого Строка из БанковскиеСчетаПоОрганизации Цикл //Каждая строка это отдельный лист в Excel
			Если Строка.Галочка Тогда
				Запрос = Новый Запрос;
				Запрос.Текст =
				"ВЫБРАТЬ
				|	Выписка.Ссылка КАК Ссылка
				|ИЗ
				|	Документ.Выписка КАК Выписка
				|ГДЕ
				|	Выписка.Организация В (&СписокОрганизаций)
				|	И Выписка.Дата >= &ДатаНачала И Выписка.Дата <= &ДатаОкончания
				|	И Выписка.БанковскийСчет = &БанковскийСчет";
				Запрос.УстановитьПараметр("СписокОрганизаций", СписокОрганизаций);
				Запрос.УстановитьПараметр("ДатаНачала", Период.ДатаНачала);
				Запрос.УстановитьПараметр("ДатаОкончания", Период.ДатаОкончания);
				Запрос.УстановитьПараметр("БанковскийСчет", Строка.Ссылка);
				
				РезультатЗапроса = Запрос.Выполнить().Выбрать();
				МассивВыписок = Новый Массив;
				Пока РезультатЗапроса.Следующий() Цикл
					МассивВыписок.Добавить(РезультатЗапроса.Ссылка);
				КонецЦикла;
		        Если МассивВыписок.Количество() > 0 Тогда
					Об = РеквизитФормыВЗначение("Объект");
					
					СтруктураВозврата = Об.СформироватьТабДок(МассивВыписок, Организация.Значение, Строка.Ссылка, Период.ДатаНачала);
			
					АдресХр = ПоместитьВоВременноеХранилище(СтруктураВозврата["ТабДок"], Новый УникальныйИдентификатор);
				    Сообщить("Высота: " + СтруктураВозврата["ТабДок"].ВысотаТаблицы + " Ширина: " + СтруктураВозврата["ТабДок"].ШиринаТаблицы);
					ВысотаВсех = ВысотаВсех + СтруктураВозврата["ТабДок"].ВысотаТаблицы;
					ШиринаВсех = ШиринаВсех + СтруктураВозврата["ТабДок"].ШиринаТаблицы;
					
					Если ЗначениеЗаполнено(Строка.Ссылка.АА_НаименованиеКраткое) Тогда
						ИмяЛиста = Строка.Ссылка.АА_НаименованиеКраткое + "," + Строка.ВалютаДенежныхСредств;
					Иначе
						ЛеваяКавычка = СтрНайти(Строка.Ссылка.Банк.Наименование, Символ(34));
						Если ЛеваяКавычка = 0 Тогда
							ИмяЛиста = Организация.Значение.Префикс + " " + Строка.Ссылка.Банк.Наименование;
						Иначе
							ПраваяКавычка = СтрНайти(Строка.Ссылка.Банк.Наименование, Символ(34),,ЛеваяКавычка+1);
							ВзятьСимволов = ПраваяКавычка - ЛеваяКавычка;
							ИмяЛиста = Организация.Значение.Префикс + " " + Сред(Строка.Ссылка.Банк.Наименование,ЛеваяКавычка+1,ВзятьСимволов-1) + "," + Строка.ВалютаДенежныхСредств;	
						КонецЕсли;
					КонецЕсли;
					
					КлючЛиста = (""+ИмяЛиста+"");
					МассивЛистов.Вставить(КлючЛиста, АдресХр);
				
					нс = Объект.СуммыПоСчетам.Добавить();
					нс.Счет = Строка.Ссылка;
					нс.СуммаПоСчету = СтруктураВозврата["СуммаПоСчету"];
					нс.КраткоеНаименованиеСчета = ИмяЛиста;
					нс.Организация = Организация.Значение;
				КонецЕсли;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
	
	ВыгрузкаСумм = Объект.СуммыПоСчетам.Выгрузить();
	Если ВыгрузкаСумм.Количество() > 0 И СписокОрганизаций.Количество() = 1 Тогда
		ТабДокИтогов = Об.СформироватьЛистИтогов(СписокОрганизаций, ВыгрузкаСумм, Период.ДатаНачала);
		Сообщить("Высота: " + ТабДокИтогов.ВысотаТаблицы + " Ширина: " + ТабДокИтогов.ШиринаТаблицы);
		ВысотаВсех = ВысотаВсех + ТабДокИтогов.ВысотаТаблицы;
		ШиринаВсех = ШиринаВсех + ТабДокИтогов.ШиринаТаблицы;
	ИначеЕсли ВыгрузкаСумм.Количество() = 0 И СписокОрганизаций.Количество() = 1 Тогда 
		Сообщить("По данной организации нет истории выписок " + СписокОрганизаций[0].Значение);
		Возврат Ложь;
	КонецЕсли;
	
	Сообщить("Высота всех: " + ВысотаВсех + " Ширина всех: " + ШиринаВсех);
	АдресХрИтогов = ПоместитьВоВременноеХранилище(ТабДокИтогов, Новый УникальныйИдентификатор);
	
	МассивЛистовИтоговый = Новый Соответствие;
	МассивЛистовИтоговый.Вставить("Итого", АдресХрИтогов);
	
	Для каждого Элемент из МассивЛистов Цикл
		МассивЛистовИтоговый.Вставить(Элемент.Ключ, Элемент.Значение);
	КонецЦикла;

	ДанныеФайла = Новый Соответствие;
	ДанныеФайла.Вставить("Каталог", Каталог);
	ДанныеФайла.Вставить("МассивЛистов", МассивЛистовИтоговый);
	
	Возврат ДанныеФайла;
КонецФункции

// Сохраняет табличные документы в файл Эксель
//
// Параметры:
// ИмяФайла — Строка — указывающая имя сохраняемого файла.
//     Можно включить полный путь;
// МассивДанных — Массив — массив соответствий:
//   * ДанныеЛиста — соответствие:
//     ** АдресВХранилище — адрес табличного документа во временном хранилище
//     ** Имя — имя листа.
&НаКлиенте
Процедура СформироватьФайлПакетом(Каталог, МассивЛистов)
	Пакет = Новый ПакетОтображаемыхДокументов;
  	Для Каждого ДанныеЛиста Из МассивЛистов Цикл
		АдресВХранилище = ДанныеЛиста.Значение;
		ЭлементПакета = Пакет.Состав.Добавить();
		ЭлементПакета.Наименование = ДанныеЛиста.Ключ;
		ЭлементПакета.Данные = АдресВХранилище;
  	КонецЦикла;
	
	ПутьКФайлу = Каталог + "\" + НазваниеФайла + ".xlsx";
	Попытка
		Пакет.Записать(ПутьКФайлу, ТипФайлаПакетаОтображаемыхДокументов.XLSX);
		Сообщить("Файл выгружен в " + ПутьКФайлу);
	  Исключение
		Сообщить("Ошибка выгрузки в " + ПутьКФайлу);
		Сообщить(ОписаниеОшибки());
	КонецПопытки;
	
КонецПроцедуры // СформироватьФайлПакетом()
Показать
Прикрепленные файлы:
ОтчетВExcel_ДДС 7.0.epf
Найденные решения
8. starik-2005 3180 05.12.23 07:49 Сейчас в теме
(7)
двигаться
// функция где-то на сервере...
Пакет.Записать(ИмяВременногоФайла, ЧтоТоТамТипДанныхЭксель);
Возврат Новый ДвоичныеДанные(ИмяВременногоФайла);
//...


// где-то на клиенте...
ДанныеФайла = ПолучитьДвоичныеДанныеФайлаССервера();
ДанныеФайла.Записать(ИмяФайлаНаКлиентеXLSX);
Показать
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. starjevschik 04.12.23 08:07 Сейчас в теме
Поставь счетчики и увидишь, сколько листов и строк делаешь.
Хотя сама идея делать ексель пусть даже 500х100 вызывает сомнения. Нафига он нужен-то такой? кто в этом будет копаться и зачем?
3. Redempty 04.12.23 08:10 Сейчас в теме
(2)
Поставь счетчики и увидишь, сколько листов и строк делаешь.
Хотя сама идея делать ексель пусть даже 500х100 вызывает сомнения. Нафига он нужен-то такой? кто в этом будет копаться и зачем?


Поставил, в коде есть эти счетчики (отсюда и взял 500х100). Суть в том, что сами по себе листы не очень объемные. А гл. буху нужен отчет по всем организациям в одном файле, вариант сформировать несколько книг по каждой из организаций не устроил, нужно именно в одной
(2)
4. user1880116 04.12.23 08:29 Сейчас в теме
(3)
в коде есть эти счетчики
Причем ТабДокИтогов ты благоразумно решил в них не учитывать.
5. Redempty 04.12.23 08:50 Сейчас в теме
(4) Резонно. Исправил, но это все еще далеко от решения проблемы, получилось:

Высота всех: 350 Ширина всех: 40

Дело явно в чем-то другом
6. starik-2005 3180 04.12.23 11:03 Сейчас в теме
А зачем Вы пакет на клиенте делаете? Сохраните его на сервере и передайте в виде двоичных данных на клиент, где уже их сохраните с нужным именем файла.
7. Redempty 05.12.23 04:20 Сейчас в теме
(6) Я первый раз в таком формате работаю с экселем, как получилось и понял, так реализовал) С двоичными данными не приходилось работать вовсе пока что. Это надо во что-то засунуть все ТабДоки (Листы) на сервере, вернуть их на клиент и там уже в пакет упаковывать, давая имена листам? Можете подсказать, в каком направлении двигаться
8. starik-2005 3180 05.12.23 07:49 Сейчас в теме
(7)
двигаться
// функция где-то на сервере...
Пакет.Записать(ИмяВременногоФайла, ЧтоТоТамТипДанныхЭксель);
Возврат Новый ДвоичныеДанные(ИмяВременногоФайла);
//...


// где-то на клиенте...
ДанныеФайла = ПолучитьДвоичныеДанныеФайлаССервера();
ДанныеФайла.Записать(ИмяФайлаНаКлиентеXLSX);
Показать
9. Redempty 06.12.23 07:04 Сейчас в теме
(8)
ДвоичныеДанные


Спасибо огромное, все получилось. Не понятно, конечно, почему при передаче соответствия он ругался, а с двоичными данными все сработало.

Может кому-то когда-то поможет, для моей задачи формирование пакета выглядит вот так:

&НаСервере
КакаяТоФункция
        //Формируем пакет
	ПакетСВременнымФайлом = Новый ПакетОтображаемыхДокументов;
	
	//Первым вставляем лист итогов
	ЭлементПакета = ПакетСВременнымФайлом.Состав.Добавить();
	ЭлементПакета.Наименование = "Итого";
	ЭлементПакета.Данные = АдресХрИтогов;
	
	//Далее остальные листы
  	Для Каждого ДанныеЛиста Из МассивЛистов Цикл
		АдресВХранилище = ДанныеЛиста.Значение;
		ЭлементПакета = ПакетСВременнымФайлом.Состав.Добавить();
		ЭлементПакета.Наименование = ДанныеЛиста.Ключ;
		ЭлементПакета.Данные = АдресВХранилище;
  	КонецЦикла;
	
	//Записываем пакет во временный файл
	ПутьКВременномуФайлу = Каталог + "\" + "Временный" + ".xlsx";
	Попытка
		ПакетСВременнымФайлом.Записать(ПутьКВременномуФайлу, ТипФайлаПакетаОтображаемыхДокументов.XLSX);
	Исключение
		Сообщить(ОписаниеОшибки());
	КонецПопытки;
	
	//Возвращаем на клиент в виде двоичных данных
	Возврат Новый ДвоичныеДанные(ПутьКВременномуФайлу);
КонецКакойТоФункции

&НаКлиенте
КакаяТоПроцедура
        ПакетСВременнымФайлом = СоздатьКнигуНаСервере();
	ПутьКФайлу = Каталог + "\" + НазваниеФайла + ".xlsx";
	Попытка
		ПакетСВременнымФайлом.Записать(ПутьКФайлу);
		Сообщить("Файл выгружен в " + ПутьКФайлу);
	Исключение
		Сообщить("Ошибка выгрузки в " + ПутьКФайлу);
		Сообщить(ОписаниеОшибки());
	КонецПопытки;
КонецКакойТоПроцедуры
Показать
Оставьте свое сообщение

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