Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
21 ноя 2024, 16:30

Как коммандно добавлять и заполнять строки ТЧ в уже существующем документе?

Автор TreeDogNight, 14 мая 2014, 16:12

0 Пользователей и 1 гость просматривают эту тему.

TreeDogNight

Делаю обработку, которая создаёт в табличной части уже существующих документов строки и заполняет их с эксэлевского документа.

Вот весь код из процедуры:
Если Не ПустаяСтрока(Объект.ФайлЗагрузки) Тогда

Exel = Новый COMОбъект("Excel.Application");
Exel.Workbooks.Open(Объект.ФайлЗагрузки);


T = 2;
Пномер     = СокрЛП(Exel.Worksheets(1).Cells(T,1).Value);
СпрЕдИзм   = Справочники.ЕдиницыИзмерения;

Пока Не ПустаяСтрока(Пномер) Цикл
Пномер = СокрЛП(Exel.Worksheets(1).Cells(T,1).Value);
НомДовер = СокрЛП(Exel.Worksheets(1).Cells(T,2).Value);
НомСтр = СокрЛП(Exel.Worksheets(1).Cells(T,3).Value);
Товары = СокрЛП(Exel.Worksheets(1).Cells(T,4).Value);
ЕдИзм = СокрЛП(Exel.Worksheets(1).Cells(T,5).Value);
Колво = СокрЛП(Exel.Worksheets(1).Cells(T,6).Value);
Если ЗначениеЗаполнено(Колво) Тогда
Колво = Число(Колво);
Иначе
Колво = 1;
КонецЕсли;

                                                       
Довер = Документы.Доверенность.НайтиПоРеквизиту("НомерДоверенности","С" + НомДовер).ПолучитьОбъект();

//Заполняем ТЧ Материалы:
Довер.ТМЦ.Очистить();
ТЧ = Довер.ТМЦ.Добавить();
ТЧ.ТМЦ = "Картошка";


Довер.Записать();

T = T + 1;
КонецЦикла;

Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не выбран файл загрузки";
Сообщение.Сообщить();
КонецЕсли;

Exel.Quit();


Я думаю, что что-то неправильно я сделал в этой части:
Довер = Документы.Доверенность.НайтиПоРеквизиту("НомерДоверенности","С" + НомДовер).ПолучитьОбъект();

//Заполняем ТЧ Материалы:
Довер.ТМЦ.Очистить();
ТЧ = Довер.ТМЦ.Добавить();
ТЧ.ТМЦ = "Картошка";


Довер.Записать();


Подскажите, в чём моя ошибка?

KrivosheevEV


TreeDogNight

Цитата: KrivosheevEV от 14 мая 2014, 16:25
Может спросишь у отладчика. Он вредный, но справедливый.
Уже спрашивал. Все реквезиты ТЧ заполняются нормально. Проблема в том, что созданные строки ТЧ не записываются в документы.

mixqn

Цитата: TreeDogNight от 14 мая 2014, 16:12Довер = Документы.Доверенность.НайтиПоРеквизиту("НомерДоверенности","С" + НомДовер).ПолучитьОбъект();         
         
         //Заполняем ТЧ Материалы:
         Довер.ТМЦ.Очистить();
         ТЧ = Довер.ТМЦ.Добавить();
         ТЧ.ТМЦ = "Картошка";
         
         
         Довер.Записать();
все просто: выше процитированный код приводит к тому, что получается документ. содержащий ровно 1 строку - последнюю добавленную.
Чтобы добавить все строки, а не одну не нужно каждый раз в цикле очищать таб часть перед добавлением строки. Так же не нужно в цикле записывать.
Ну и чтобы сделать совсем все красиво и по уму, вам надо не напрямую их экселья в доки писать и искать их методом НайтиПоРеквизиту, а сначала из экселя все данные сложить в иаблицу значений, затем используя эту таблицу запросом выбрать сразу все документы одним запросом, а не в цикле и уже циклом по результату запроса обработать документы.

Было бы время, наваял бы для вас готовый код, но не получится ))
Попробуйте сами, опираясь на текст выше.

TreeDogNight

Я на правильном пути?)


                        КЧ = Новый КвалификаторыЧисла(12,2);
КС = Новый КвалификаторыСтроки(20);
Массив = Новый Массив;
Массив.Добавить(Тип("Строка"));
ОписТипС = Новый ОписаниеТипов(Массив, , КС);
Массив.Очистить();
Массив.Добавить(Тип("Число"));
ОписТипЧ = Новый ОписаниеТипов(Массив, , ,КЧ);
Массив.Добавить(Тип("СправочникСсылка.ЕдиницыИзмерения"));
ОписТипЕд = Новый ОписаниеТипов(Массив, , ,КЧ);

ТЗ = Новый ТаблицаЗначений;
                        ТЗ.Колонки.Добавить("НомерДоверенности",ОписТипС,"НомерДоверенности",15);
ТЗ.Колонки.Добавить("ТМЦ", ОписТипС, "ТМЦ", 70);
ТЗ.Колонки.Добавить("ЕдИзм", ОписТипЕд, "ЕдИзм", 15);
ТЗ.Колонки.Добавить("Количество", ОписТипЧ, "Количество", 30);

                        Пока Не ПустаяСтрока(Пномер) Цикл
Пномер = СокрЛП(Exel.Worksheets(1).Cells(T,1).Value);
НомДовер = СокрЛП(Exel.Worksheets(1).Cells(T,2).Value);
НомСтр = СокрЛП(Exel.Worksheets(1).Cells(T,3).Value);
Товары = СокрЛП(Exel.Worksheets(1).Cells(T,4).Value);
ЕдИзм = СокрЛП(Exel.Worksheets(1).Cells(T,5).Value);
Колво = СокрЛП(Exel.Worksheets(1).Cells(T,6).Value);
Если ЗначениеЗаполнено(Колво) Тогда
Колво = Число(Колво);               
Иначе
Колво = 1;
КонецЕсли;

Если НЕ ЗначениеЗаполнено(Товары) Тогда
Товары = "Неизвестный товар";
КонецЕсли;

Если НЕ ЗначениеЗаполнено(ЕдИзм) Тогда
ЕдИзм = "шт";
КонецЕсли;


Стр   = ТЗ.Добавить();
Стр.НомерДоверенности = "С" + НомДовер;
Стр.ТМЦ       = Товары;
Стр.ЕдИзм       = ЕдИзм;
Стр.Количество   = Колво;

T = T + 1

КонецЦикла;

cska-fanat-kz

ТЗ не обязательно создавать программно. Бросьте на форму табличное поле и мышой задайте нужные Вам колонки (включая их тип).
Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

TreeDogNight

Сделал вот так, но все равно строки не записываются в ТЧ.

Если Не ПустаяСтрока(Объект.ФайлЗагрузки) Тогда

Exel = Новый COMОбъект("Excel.Application");
Exel.Workbooks.Open(Объект.ФайлЗагрузки);


T = 2;
Пномер     = СокрЛП(Exel.Worksheets(1).Cells(T,1).Value);
СпрЕдИзм   = Справочники.ЕдиницыИзмерения;

КЧ     = Новый КвалификаторыЧисла(12,2);
КС     = Новый КвалификаторыСтроки(20);
Массив = Новый Массив;
Массив.Добавить(Тип("Строка"));
ОписТипС  = Новый ОписаниеТипов(Массив, , КС);
Массив.Очистить();
Массив.Добавить(Тип("Число"));
ОписТипЧ  = Новый ОписаниеТипов(Массив, , ,КЧ);
Массив.Добавить(Тип("СправочникСсылка.ЕдиницыИзмерения"));
ОписТипЕд = Новый ОписаниеТипов(Массив, , ,КЧ);


ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("НомерДоверенности",ОписТипС,"НомерДоверенности",15);
ТЗ.Колонки.Добавить("ТМЦ", ОписТипС, "ТМЦ", 70);
ТЗ.Колонки.Добавить("ЕдИзм", ОписТипС, "ЕдИзм", 15);
ТЗ.Колонки.Добавить("Количество", ОписТипЧ, "Количество", 30);

Пока Не ПустаяСтрока(Пномер) Цикл
Пномер = СокрЛП(Exel.Worksheets(1).Cells(T,1).Value);
НомДовер = СокрЛП(Exel.Worksheets(1).Cells(T,2).Value);
НомСтр = СокрЛП(Exel.Worksheets(1).Cells(T,3).Value);
Товары = СокрЛП(Exel.Worksheets(1).Cells(T,4).Value);
ЕдИзм = СокрЛП(Exel.Worksheets(1).Cells(T,5).Value);
Колво = СокрЛП(Exel.Worksheets(1).Cells(T,6).Value);
Если ЗначениеЗаполнено(Колво) Тогда
Колво = Число(Колво);               
Иначе
Колво = 1;
КонецЕсли;

    Если НЕ ЗначениеЗаполнено(Товары)Тогда                                     
    Товары = "Неизвестный товар";                                             
    КонецЕсли;

Если НЕ ЗначениеЗаполнено(ЕдИзм) ИЛИ ЕдИзм = "" Тогда
ЕдИзм = "шт";
КонецЕсли;


Стр               = ТЗ.Добавить();
Стр.НомерДоверенности = "С" + НомДовер;
Стр.ТМЦ       = Товары;
Стр.ЕдИзм       = Справочники.ЕдиницыИзмерения.НайтиПоНаименованию(ЕдИзм);
Стр.Количество       = Колво;

T = T + 1

КонецЦикла;

Для каждого Стр из ТЗ Цикл

Довер = Документы.Доверенность.НайтиПоРеквизиту("НомерДоверенности", Стр.НомерДоверенности).ПолучитьОбъект();


//Заполняем ТЧ Материалы:
ТЧ = Довер.ТМЦ.Добавить();
ТЧ.ТМЦ = Стр.ТМЦ;
ТЧ.Количество = Стр.Количество;
ТЧ.ЕдИзм = Справочники.ЕдиницыИзмерения.НайтиПоНаименованию(Стр.ЕдИзм);


Если Довер.Модифицированность() Тогда
Сообщить("Доверенность № " + Стр.НомерДоверенности + " успешно изменена");
КонецЕсли;

Довер.Записать();
КонецЦикла;

Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не выбран файл загрузки";
Сообщение.Сообщить();
КонецЕсли;

Exel.Quit();


Когда в отлатчике рассчитываю выражение "Довер.Записать()" в колонке значение пишет "{(1)}: Обращение к процедуре объекта как к функции (Записать)".

cska-fanat-kz

Цитата: TreeDogNight от 15 мая 2014, 10:30Когда в отлатчике рассчитываю выражение "Довер.Записать()" в колонке значение пишет "{(1)}: Обращение к процедуре объекта как к функции (Записать)".

Правильно пишет. Вы же от процедуры Записать() пытаетесь какое-то значение получить, как от функции.

А по коду - на первый взгляд все правильно. Имеется ввиду в плане заполнения ТЧ и записи документа...

Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

TreeDogNight

Сейчас через отлатчик вычислил значение "Довер.ТМЦ", и к моему удивлению там оказалось целых 9 строк, хотя в табличной части этого документа нет ни одной строчки...

mixqn

Не увидел принципиального изменения в алгоритме. Да, вы сначала создали таблицу значений, но потом то опять таки в цикле ищите документы, там же в цикле их записываете и там же строки добавляете. Принципиальное отличие только одно - Довер.ТМЦ.Очистить(); не стало.

Попробую объяснить еще раз :)
У вас принципиальная ошибка в алгоритме что в первом, что во втором случае - вы один документ записываете несколько раз, при чем не очистив перед заполнением таб часть. Последнее означает, что при каждой загрузке из экселя, если их будет несколько, строки будут не заменяться по файлу, а добавляться - это вполне и может быть причиной того, что у вас 9 строк в таб. части.

Как надо сделать:
1. первый шаг у вас есть - собрать данные в таблицу значений
2. выбрать все документы, которые необходимо модифицировать.
3. обрабатывать 1 документ сразу, не делая записи в цикле.

Далее есть 2 варианта решения:
1. Запросом
2. Без запроса.

Запрос если время будет попозже попробую набросать примерный, идея в том, что там можно получить прямо готовые таблицы для заполнения документов и код вообще будет максимально прост, понятен и красив :)

Вариант без запроса выглядит так:
1. выгружаете колонку ("НомерДоверенности" если не ошибаюсь), по которой вы ищите доки в отдельную таблицу значений
2. сворачиваете полученную новую ТЗ по этой колонке, выгружаете ее в массив (последнее не обязательно, можно гнать цикл и по таблице из 1 колонки). на этом шаге вы получаете список всех уникальных идентификаторов документов, которые надо обработать.
3. бежите циклом по полученному списку (не важно, в каком виде - ТЗ, или массив), выбираете по НомерДоверенности документ из базы, очищаете таб. часть, далее методом НайтиСтроки выбираете в первоначальной таблице (полученной выше путем обработки экселя) все строки с таким НомерДоверенности, бежите во вложенном цикле по этим строкам, добавляете их в документ, после завершения вложенного цикла записываете док.

как-то так

Теги:

Похожие темы (5)

Рейтинг@Mail.ru

Поиск