Всем доброе время суток ! Пытаюсь заполнить табличную часть документа "Установка цен номенклатуры" из файла excel. Что делаю не так ?
Проблема в том, что на форме объекта табличная часть это реквизит, а не объект. В связи с этим вылазит ошибка, мол "Заполнение ТЧ не произведено!
Поле объекта не обнаружено (ТаблицаЦен)" Подскажите как решить.
Процедура Инициализировать(Объект, ИмяТабличнойЧасти, ТабличноеПоле) Экспорт;
ТабличнаяЧасть = Объект[ИмяТабличнойЧасти];
ДиалогВыбора = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ДиалогВыбора.Заголовок = "Выберите файл";
Если ДиалогВыбора.Выбрать() Тогда
ИмяФайла = ДиалогВыбора.ПолноеИмяФайла;
КонецЕсли;
//подключаемся к эксель
Попытка
Excel = Новый COMОбъект("Excel.Application");
Excel.WorkBooks.Open(ИмяФайла);
Состояние("Обработка файла Microsoft Excel...");
Исключение
Сообщить("Ошибка при открытии файла с помощью Excel! Загрузка не будет произведена!");
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
Попытка
//Открываем необходимый лист
Excel.Sheets(1).Select(); // лист 1, по умолчанию
Исключение
//Закрываем Excel
Excel.ActiveWorkbook.Close();
Excel = 0;
Сообщить("Файл "+Строка(ИмяФайла)+" не соответствует необходимому формату! Первый лист не найден!");
ОтменитьТранзакцию();
Возврат;
КонецПопытки;
//Получим количество строк и колонок.
//В разных версиях Excel получаются по-разному, поэтому сначала определим версию Excel
Версия = Лев(Excel.Version,Найти(Excel.Version,".")-1);
Если Версия = "8" тогда
ФайлСтрок = Excel.Cells.CurrentRegion.Rows.Count;
ФайлКолонок = Макс(Excel.Cells.CurrentRegion.Columns.Count, 13);
Иначе
ФайлСтрок = Excel.Cells(1,1).SpecialCells(11).Row;
ФайлКолонок = Excel.Cells(1,1).SpecialCells(11).Column;
Конецесли;
Для а = 2 по ФайлСтрок Цикл
Для Каждого Стр из ТабличнаяЧасть Цикл
Стр.Номенклатура = СокрЛП(Excel.Cells(а,4).Value);
КонецЦикла;
КонецЦикла;
Excel.DisplayAlerts = 0;
Excel.Quit();
Excel.DisplayAlerts = 1;
КонецПроцедуры
44.
Intercititude
15.01.20 13:57 Сейчас в теме+0.56 $m
(42) Ну по сути я у своей обработки создам форму в которой будет тч заполняться данными из Excel и потом уже переноситься в документ со всеми этими махинациями с открытием и прочим. Так ?
стандартная обработка загрузки из эксель не подходит, потому что в документе установка - 2 тч. Во второй тч перечислены типы цен, но если 2-я тч не заполнена ничего корректно не будет работать
(4) Как быть ? Подразумевается,что сперва пользователь выбирает ТипЦен. А затем жмёт заполнить с помощью обработки. И из файла Excel в которым три колонки Код|Наименование|Цена заполняется тч.
я бы на твоем месте взял любую загрузку из эксель и переделал её под заполнение табличной части Товары конкретного документа Установка цен, с одним типом цены.
(10) тоже вот не нашёл. В итоге сделал так, но не могу найти где то подвох. Ничего не заполняет. Может вы опытный взглядом подскажете ?
Процедура Инициализировать(Объект, ИмяТабличнойЧасти = Неопределено , ТабличноеПоле = Неопределено ) Экспорт;
ТабличнаяЧасть = Объект.Товары;
ТабличнаяЧасть.Очистить();
ДиалогВыбора = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ДиалогВыбора.Заголовок = "Выберите файл";
Фильтр ="(*.xls)|*.xlsx";
ДиалогВыбора.Фильтр = Фильтр;
Если ДиалогВыбора.Выбрать() Тогда
ИмяФайла = ДиалогВыбора.ПолноеИмяФайла;
КонецЕсли;
//подключаемся к эксель
Попытка
Excel = Новый COMОбъект("Excel.Application");
Excel.WorkBooks.Open(ИмяФайла);
Состояние("Обработка файла Microsoft Excel...");
Исключение
Сообщить("Ошибка при открытии файла с помощью Excel! Загрузка не будет произведена!");
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
Попытка
//Открываем необходимый лист
Excel.Sheets(1).Select(); // лист 1, по умолчанию
Исключение
//Закрываем Excel
Excel.ActiveWorkbook.Close();
Excel = 0;
Сообщить("Файл "+Строка(ИмяФайла)+" не соответствует необходимому формату! Первый лист не найден!");
ОтменитьТранзакцию();
Возврат;
КонецПопытки;
//Получим количество строк и колонок.
//В разных версиях Excel получаются по-разному, поэтому сначала определим версию Excel
Версия = Лев(Excel.Version,Найти(Excel.Version,".")-1);
Если Версия = "8" тогда
ФайлСтрок = Excel.Cells.CurrentRegion.Rows.Count;
ФайлКолонок = Макс(Excel.Cells.CurrentRegion.Columns.Count, 13);
Иначе
КоличествоСтрок = Excel.Cells(1,1).SpecialCells(11).Row;
КоличествоКолонок = Excel.Cells(1,1).SpecialCells(11).Column;
Конецесли;
// Проверка корректности заполнения колонок
// Имена колонок в Excel файле должны совпадать с именами реквизитов табличной части, в которую загружаются данные
// Переменная МассивКолонок содержит список номеров колонок, которые будут перегружаться
МассивКолонок = Новый ТаблицаЗначений;
МассивКолонок.Колонки.Добавить("НомерКолонки");
МассивКолонок.Колонки.Добавить("НазваниеКолонки");
Для КолонкаОтсчета = 1 по КоличествоКолонок Цикл
ИмяКолонки = Excel.Cells(1, КолонкаОтсчета).Text;
НовСтрока = МассивКолонок.Добавить();
НовСтрока.НомерКолонки = КолонкаОтсчета;
НовСтрока.НазваниеКолонки = ИмяКолонки;
КонецЦикла;
// Если есть колонки для загрузки
// и есть колонка "Номенклатура, которая является обязательным к заполнению реквизитом
Если МассивКолонок.Количество() <> 0 Тогда
// Заполнение табличной части "Товары"
// Переменная СтрокаОтсчета - номер строки в Excel, с которой начинается заполнение
Для СтрокаОтсчета = 2 по КоличествоСтрок Цикл
НСтр = ТабличнаяЧасть.Добавить();
Для каждого СтрокаМассив из МассивКолонок Цикл
ОбработкаПрерыванияПользователя();
ТекущееЗначение = Excel.Cells(СтрокаОтсчета, СтрокаМассив.НомерКолонки).Text;
// Получение имени колонки
ИмяКолонки = Excel.Cells(1, СтрокаМассив.НомерКолонки).Text;
// Заполнение строки данными
Если ИмяКолонки = "Наименование " Тогда
НСтр.Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию(ТекущееЗначение, Истина);
ИначеЕсли ИмяКолонки = "цена" Тогда
НСтр.Цена = ТекущееЗначение;
ИначеЕсли ИмяКолонки = "Код" Тогда
КонецЕсли;
КонецЦикла;
КонецЦикла;
Иначе
Сообщить("В Excel файле не достаточно данных для заполнения документа!");
КонецЕсли;
Excel.DisplayAlerts = 0;
Excel.Quit();
Excel.DisplayAlerts = 1;
КонецПроцедуры
(11) Эта загрузка заполняет только цену и номенклатуру. Нужно добавить заполнения ТипаЦены в каждой строчке тч Товары, и ещё единицу измерения, можно взять из номенклатуры умолчальную.
(12) Как раз с этим и вожусь сейчас. То есть как смогу заполнить ТипаЦены то всё заполнится ?
Вот в этом месте достаточно будет ?НСтр.ТипЦен = Справочники.ТипыЦенНоменклатуры.НайтиПоНаименованию(ТипЦен, Истина);
// Заполнение табличной части "Товары"
// Переменная СтрокаОтсчета - номер строки в Excel, с которой начинается заполнение
Для СтрокаОтсчета = 2 по КоличествоСтрок Цикл
НСтр = ТабличнаяЧасть.Добавить();
НСтр.ТипЦен = Справочники.ТипыЦенНоменклатуры.НайтиПоНаименованию(ТипЦен, Истина);
Для каждого СтрокаМассив из МассивКолонок Цикл
По идеи да. Код не полный, я так понимаю он вызывается для уже созданного документа. Т.е. в документе должн быть выбран какойто тип цен (в тч ТипыЦен будет создана строкас типом цены).
потом заполняя из эксель тчт товары с указанием этого типа цен, всё должно сложиться
(18) Думаю, что проблема в том, что при загрузке обработки предлагается выбор только одной ТЧ ТаблицаЦен(создана как реквизит на форме объекта) . А я пытаюсь заполнить ТЧ Товары. Не пойму как решить этот вопрос.
(18) Проверил отладчиком . ТабличнаяЧасть заполняется данными из excel наименованием. типом цен и ценой. Но в итоге в табличную часть документа не выводит..
(21) Поддерживаю, при записи все строки табличной части "Товары" с Типом цен, отсутствующим в табличной части "ТипыЦен" игнорируются. Табличную части "ТипыЦен" так же нужно заполнять.
(21) То есть вся табличная часть "Товары" заполняется те ми же данными, что и в Excel . Правда некоторые позиции номенклатуры пустые,так как видимо нету их в базе. Ума не приложу в чем дело.. почему не заполняется документ "Установка цен номенклатуры".
еще возможно что считаный из ячейки .Text (если колонка = "Цена") когда к типу числовому приводится превращается в ноль. А нулевые цены игнорируются.
Надо .Value
Нужно переоткрыть форму документа. Реквизит формы ТаблицаЦен заполняется при открытии. ПередЗаписью из него все пишется в табличную часть Товары. Т.е. форму закрыть без сохранения если модифицированность.
И да... этот документ придется записывать. Автоматом он не обновится. Только в ПриОткрытии идет заполнение
Получается ты все табличные части заполнил. Управление вернулось на форму. А форме от этого ни холодно ни жарко - она показывает реквзит ТаблицаЦен который остался прежним.
(35) Это же обработка заполнения табличной части. То есть пользователь создал документ. Выбрал тип цен. Потом только уже в ТЧ выбирает "Заполнить из Excel". Выбирает файл Excel и вуаля.
(40) Для пользователей можно написать обработку - интерфейс установки цен. Которая по какой то логике будет и эксель читать, и предварительно результат показывать, и документы "Установка цен номенклатуры" создавать/ изменять. Это если конфигурацию нельзя менять.
FetisovAN, вы согласны с выводами? Может быть есть еще варианты?
44.
Intercititude
15.01.20 13:57 Сейчас в теме+0.56 $m
(42) Ну по сути я у своей обработки создам форму в которой будет тч заполняться данными из Excel и потом уже переноситься в документ со всеми этими махинациями с открытием и прочим. Так ?
(39)Это я по названию процедуры и переменным догадался. Вспомнил что делал так же обработку заполнения табличной части для этого документа. Только там не эксель, но не суть. Проблема в том что мы в этой процедуре на сервере можем менять объект, можем менять его табличные части, но форму и её реквизиты мы поменять не можем.
Поэтому если мы изменили табличную часть "Товары" и управление вернулось на форуму, в случае если это какой то обычный документ (например Заказ) где на форме отображается табличная часть "Товары" то наши изменения мы сразу и увидим.
А с этим документом так не получится. На форме отображается таблица, являющаяся реквизитом формы. Этот реквизит был заполнен при открытии формы. При сохранении, опять же в событии формы из этого реквизита будет перезаполнена табличная часть Товары.
В итоге некрасивый неудобный вариант - в обработке табличной части объект записать. По возврату управления на форму - форму переоткрыть. Меня в свое время устроило потому что делал для разового использования и для себя. Для пользователя этот подход конечно не подойдет.
(39) код заполнения самой табличной части - рабочий. Добавил в конец обработки Объект.Записать() и открыл и запустил её просто как внешнюю - т.ч. заполняется. А вот работа в режиме "обработка заполнения табличной части" - что-то не так ... Если честно этим почти не пользуюсь, не могу подсказать что не так.