Имя: Пароль:
1C
1С v8
Заполнение двумерной ТЗ
0 Rijen
 
11.12.14
20:21
Здравия.
Есть у меня набор данных на списание, табличка, надо три поля - склад, номенклатура, количество.
Мне приходят данные на подобии
|Склад1|Ном1|10|
|Склад1|Ном2|10|
|Склад2|Ном1|10|

Почесав за ухом я набросал такую процедуру
[code]
Процедура СписаниеЛот(Товары,КонецПериода)
    Товары2 = товары;//Фикс баги со ссылками
    ТМЗ = Новый ТаблицаЗначений;            
    ТМЗ.Колонки.Добавить("ТабНом");
    ТМЗ.Колонки.Добавить("Склад");
    
    ЭТН = Новый ТаблицаЗначений;
    ЭТН.Колонки.Добавить("Номенклатура");
    ЭТН.Колонки.Добавить("Количество");
    
    Для каждого товар из товары2 цикл
        
        СущСклад = ТМЗ.Найти(Товар.Склад,"Склад");
        Если НЕ СущСклад=Неопределено тогда
            ЭЭТН = ЭТН.Добавить();
            ЭЭТН.Номенклатура = товар.Номенклатура;
            ЭЭТН.Количество = товар.Количество;
            
            СущСклад.ТабНом = ЭТН;
        иначе
            ЭТН = Неопределено;
            ЭЭТН = ЭТН.Добавить();
            ЭЭТН.Номенклатура = товар.Номенклатура;
            ЭЭТН.Количество = товар.Количество;
            
            ЭТМЗ = ТМЗ.Добавить();
            ЭТМЗ.Склад = Товар.Склад;
            ЭТМЗ.ТабНом = ЭТН;
        конецЕсли;
    КонецЦикла;
    Для каждого ЭлСписания из ТМЗ цикл
        НовДок = Документы.СписаниеТоваров.СоздатьДокумент();
        НовДок.Склад = ЭлСписания.Склад;
        НовДок.Дата = КонецПериода;
        Для каждого НомСписания из ЭлСписания.ТабНом  цикл
            НовСтрока = НовДок.Товары.Добавить();
            НовСтрока.Номенклатура = НомСписания.Номенклатура;
            НовСтрока.Количество =НомСписания.Количество;
        КонецЦикла;
        НовДок.Записать();
    КонецЦикла;
    
КонецПроцедуры
[/code]

Но в итоге в документ попадают только последние номенклатуры по каждому из складов.
Что я сделал не так?
1 Garykom
 
гуру
11.12.14
20:23
иначе
            ЭТН = Неопределено;
            ЭЭТН = ЭТН.Добавить();

как оно вообще работает?
2 kosts
 
11.12.14
20:24
(0) Сильно не вникал, но может быть надо просто свернуть исходную ТЗ?...
3 Garykom
 
гуру
11.12.14
20:24
(1)+ 100% не за тем ухом почесал ))
4 Ник второй
 
11.12.14
20:24
Какой результат нужен, свернутая ТЗ?
5 Rijen
 
11.12.14
20:25
(1) Я ожидаю что так я очищу состояние предыдущей итерации.
6 Ник второй
 
11.12.14
20:25
(3) Может он так отлаживает ))) если нет ошибки, то эту ветку можно удалить )
7 Ник второй
 
11.12.14
20:25
(5) рука лицо.
8 Garykom
 
гуру
11.12.14
20:26
(7) +1
9 Rijen
 
11.12.14
20:27
Я ожидаю структуру:
[ТМЗ] =>{
    [Склад] = >'Склад бла-бла'
    [ТабЗН]=> {
     [Номенклатура]=>'Ном1',[Количество]=>11,
     [Номенклатура]=>'Ном2',[Количество]=>11
    }

}
Но не очень осознаю как создать многомерный объект.
10 kosts
 
11.12.14
20:28
(9) А оно тебе надо. Создавать многомерный объект...
11 Garykom
 
гуру
11.12.14
20:29
(7) судя по (9) оно не поняло ))
12 Rijen
 
11.12.14
20:29
Тьфуты.
ЭТН = Неопределено;
там и не должно быть.
13 Rijen
 
11.12.14
20:30
(10) Мне надо разбить по складам. Придумал только так =)
14 Ник второй
 
11.12.14
20:31
(13) Зачем тебе нужно разбить по складам? Какая задача.
15 Garykom
 
гуру
11.12.14
20:34
(13) мужик, это же не 7.7, такие проблемы решают через запросы...
16 Rijen
 
11.12.14
20:34
(14) На входе есть табдок:
|Склад1|Ном1|10шт|
|Склад1|Ном2|10|
|Склад2|Ном1|10|
Мне надо его списать. Документик списания товаров не принимает склад в табличную часть, а на каждую номенклатуру нельзя создавать документ списания.
Следовательно надо разбить гору номентклатуры, с создать документ списания с одного склада, потом с другого.
17 Rijen
 
11.12.14
20:35
(15) Запрашивать некуда. Данных на необходимый момент создания докуметов нет в базе.
18 kosts
 
11.12.14
20:35
Ну не знаю, как-то так можно


ИсходнаяТЗ.Свернуть("Склад, Номенклатура", "Количество");

ТЗСклады = ИсходнаяТЗ.ВыгрузитьСтроки(,"Склад");
ТЗСклады.Свернуть("Склад");

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

   СтрокиПоСкладу = ИсходнаяТЗ.Найтистроки(Новый Структура("Склад", т.Склад));

   НовДок = Документы.СписаниеТоваров.СоздатьДокумент();
   НовДок.Склад = т.Склад;
   НовДок.Дата = КонецПериода;
  
   Для Каждого т1 из СтрокиПоСкладу Цикл
        НовСтрока = НовДок.Товары.Добавить();
        НовСтрока.Номенклатура = т1.Номенклатура;
        НовСтрока.Количество = т1.Количество;
    КонецЦикла;

    НовДок.Записать();

КонецЦикла;
19 Rijen
 
11.12.14
20:36
Создать временный справочник для хранения всего этого хлама, и от туда запросом?
20 Garykom
 
гуру
11.12.14
20:36
(16) Свернуть получаешь список складов

затем цикл двойной сначала по складу, затем по твоей ТЗ с условием что Склад = ТЗ.Склад
21 Garykom
 
гуру
11.12.14
20:37
(18) найти убери оно нафик не надо
22 Garykom
 
гуру
11.12.14
20:39
(21) хотя не можно и так но у тя больше операций в результате, по моему методу быстрее
23 kosts
 
11.12.14
20:44
(22) Не факт, надо еще где-то склады/документы по середине процесса держать.
А найти строки это встроеннный метод, должен быстро работать, если еще и проиндексировать ТЗ.
24 Garykom
 
гуру
11.12.14
21:04
(23) Можно еще проще ))

добавить поле Документ в исходную таблицу Товары и циклу по Товары для заполнения документов

итого все в 2 цикла по Товары укладывается плюс поиск по таблице Склад - Документ.Ссылка
25 Rijen
 
11.12.14
21:20
Немного получался, в итоге корректно работающая функция выглядит так..

Процедура СписаниеЛот(Товары,КонецПериода)
    ТЗ1 = Новый ТаблицаЗначений;     
    ТЗ1.Колонки.Добавить("Склад"); ;
    
    Для каждого товар из товары цикл
        новТЗ1 = ТЗ1.Добавить();
        новТЗ1.Склад =    товар.Склад      ;
    КонецЦикла;
    
    ТЗ2 = Новый ТаблицаЗначений;
    ТЗ2.Колонки.Добавить("Номенклатура");
    ТЗ2.Колонки.Добавить("Склад");
    ТЗ2.Колонки.Добавить("Количество");
    
    Для каждого товар из товары цикл
        новТЗ2 = ТЗ2.Добавить();
        новТЗ2.Номенклатура =товар.Номенклатура  ;
        новТЗ2.Склад =    товар.Склад      ;
        новТЗ2.Количество =   товар.Количество ;
    КонецЦикла;

    ТЗ1.Свернуть("Склад");
    
    Для Каждого т из ТЗ1 Цикл
        НовДок = Документы.СписаниеТоваров.СоздатьДокумент();
        НовДок.Склад = т.Склад;
        НовДок.Дата = КонецПериода;
        
        Для Каждого т1 из ТЗ2 Цикл
            Если т1.Склад = т.Склад тогда
                НовСтрока = НовДок.Товары.Добавить();
                НовСтрока.Номенклатура = т1.Номенклатура;
                НовСтрока.Количество = т1.Количество;
            конецЕсли;
        КонецЦикла;
        
        НовДок.Записать();
    КонецЦикла;
    
КонецПроцедурыПроцедура СписаниеЛот(Товары,КонецПериода)
    ТЗ1 = Новый ТаблицаЗначений;     
    ТЗ1.Колонки.Добавить("Склад"); ;
    
    Для каждого товар из товары цикл
        новТЗ1 = ТЗ1.Добавить();
        новТЗ1.Склад =    товар.Склад      ;
    КонецЦикла;
    
    ТЗ2 = Новый ТаблицаЗначений;
    ТЗ2.Колонки.Добавить("Номенклатура");
    ТЗ2.Колонки.Добавить("Склад");
    ТЗ2.Колонки.Добавить("Количество");
    
    Для каждого товар из товары цикл
        новТЗ2 = ТЗ2.Добавить();
        новТЗ2.Номенклатура =товар.Номенклатура  ;
        новТЗ2.Склад =    товар.Склад      ;
        новТЗ2.Количество =   товар.Количество ;
    КонецЦикла;

    ТЗ1.Свернуть("Склад");
    
    Для Каждого т из ТЗ1 Цикл
        НовДок = Документы.СписаниеТоваров.СоздатьДокумент();
        НовДок.Склад = т.Склад;
        НовДок.Дата = КонецПериода;
        
        Для Каждого т1 из ТЗ2 Цикл
            Если т1.Склад = т.Склад тогда
                НовСтрока = НовДок.Товары.Добавить();
                НовСтрока.Номенклатура = т1.Номенклатура;
                НовСтрока.Количество = т1.Количество;
            конецЕсли;
        КонецЦикла;
        
        НовДок.Записать();
    КонецЦикла;
    
КонецПроцедуры


Это нормальная реализация? Меня смущает копирование объекта, но иначе не получается..
26 Rijen
 
11.12.14
21:21
Прошу прощения, не заметил дубля.
27 Куро
 
11.12.14
22:08
сделай запросом
28 su_mai
 
11.12.14
22:16
(0) Главное что сделано не так, это именно то, что в одном методе собрано множество блоков кода выполняющих различные, атомарные по своей прикладной сути, действия с таблицей значений. Если их выделить в отдельные методы то алгоритм обработки данных не будет скрыт за строчками кода. Кроме того, при программировании не будет применяться метод "КопиПаста" порождающий трудно диагностируемые ошибки.
29 hhhh
 
11.12.14
23:23
(13) а зачем поле ТабНом, если там всегда одна и та же таблица ЭТН?
AdBlock убивает бесплатный контент. 1Сергей