Имя: Пароль:
1C
1С v8
Удаление строк в документе
,
0 spapin87
 
11.07.13
12:00
Добрый день. Подскажите, хочу удалить строки в документе инвентаризация у позиций, у который место хранения стоит склад "000000004". В принципе все удаляется, но не сразу приходится обработку прогнать несколько раз. В чем косяк?

Процедура КнопкаВыполнитьНажатие(Кнопка)
   Док = Документы.ИнвентаризацияТоваровНаСкладе.Выбрать();
   Пока Док.Следующий() Цикл
       Объект = Док.ПолучитьОбъект();
       Для Каждого стрТовары из Объект.Товары Цикл
           Выбсклад = Справочники.Склады.НайтиПоКоду("000000004");
           склад = стрТовары.МестоХранения.Склад.Код;                                        
           Если Выбсклад.Код = склад Тогда
               ОбработкаПрерыванияПользователя();
               Сообщить("В " + Док + ";Позиция: " + стрТовары.Номенклатура + ";находится на складе: " + стрТовары.МестоХранения.Склад + ";");
               Объект.Товары.Удалить(стрТовары);
           КонецЕсли;
       КонецЦикла;
       Объект.Записать();
   КонецЦикла;
КонецПроцедуры
1 Жан Пердежон
 
11.07.13
12:01
косяк в алгоритме, используй НайтиСтроки
2 Kreont
 
11.07.13
12:02
Перепиши удалений только снизу вверх
3 Жан Пердежон
 
11.07.13
12:03
внутри вложенного цикла:

Справочники.Склады.НайтиПоКоду("000000004");

просто красаучег
4 Cube
 
11.07.13
12:03
Баян. Когда ты удаляешь текущую строку, ты перескакиваешь на следующую автоматом и возвращаешься в начало цикла где идешь на следующую строку. То есть, при удалении строки, ты перескакиваешь через 1 строку.
5 Cube
 
11.07.13
12:03
(3) )))
6 ДенисЧ
 
11.07.13
12:04
"            Выбсклад = Справочники.Склады.НайтиПоКоду("000000004");
           склад = стрТовары.МестоХранения.Склад.Код;                                        
           Если Выбсклад.Код = склад Тогда
"

Вот это номер...
8 1Сергей
 
11.07.13
12:06
(6) ну, работает же :)
9 Cube
 
11.07.13
12:07
(6) Ахахххааа)))
10 hhhh
 
11.07.13
12:10
(0) Выбсклад.Код всегда равно "000000004"

поэтому пиши проще

      Для Каждого стрТовары из Объект.Товары Цикл
           склад = стрТовары.МестоХранения.Склад.Код;                                        
           Если "000000004" = склад Тогда
11 vicof
 
11.07.13
12:13
(10) ага, а завтра захотят по другому складу удалить строки.
(11) Для Каждого стрТовары из Объект.Товары Цикл
        Если Склад = ВыбранныйПользователемСклад Тогда
12 spapin87
 
11.07.13
12:17
Цикл для каждого не подойдет наверное в моем случае ...
13 PCcomCat
 
11.07.13
12:18
Вроде не пятница еще!;)
14 1Сергей
 
11.07.13
12:19
(12) правильный ответ дали в первом посте
15 hhhh
 
11.07.13
12:29
(12) ну тогда зачем ты его написал, если он тебе не подойдет?
16 spapin87
 
11.07.13
12:31
так я только сейчас сообразил, что буде перескакивать через строчку (((
17 Kreont
 
11.07.13
12:35
(16) во-во, см.вар.(2) для перебора снизу вверх.
18 Mitriy
 
11.07.13
12:37
(17) в (1) проще...
19 Мыш
 
11.07.13
12:51
Для Счетчик=1-Коллекция.Количество() По 0 Цикл
  ЭлементКоллекции=Коллекция[-Счетчик];
КонецЦикла;
20 Franchiser
 
гуру
11.07.13
13:04
Док1 = Док.ПолучитьОбъект();
   ТЧ=  Док1.Товары;
   НомСтроки =  ТЧ.Количество()-1;      //Номер послед. строки
   Для НСтр= -НомСтроки по 0 цикл
   ТЧ.Удалить(-НСтр);
   КонецЦикла;
   Док1.Записать();
21 1Сергей
 
11.07.13
13:12
Изобретатели, мля. Поторюсь, правильный ответ был дан ещё в (1)

Процедура КнопкаВыполнитьНажатие(Кнопка)
   Док = Документы.ИнвентаризацияТоваровНаСкладе.Выбрать();
   Пока Док.Следующий() Цикл
       Объект = Док.ПолучитьОбъект();
       НайденныеСтроки = Объект.Товары.НайтиСтроки(Новый Структура("Склад", Справочники.Склады.НайтиПоКоду("000000004")));
       Для Каждого СтрокаКУдалению из НайденныеСтроки Цикл
           Объект.Товары.Удалить(СтрокаКУдалению);
       КонецЦикла;
       Объект.Записать();
   КонецЦикла;
КонецПроцедуры
22 Мыш
 
11.07.13
13:12
(21) Это неспортивно )
23 Franchiser
 
гуру
11.07.13
13:15
Такое удаление еще в ЗИКе было, ничего не изобретаю.
В Типовой 1с 8 Бух код (Справочник Типовые операции) пжл:
Для Сч = -НачИндекс По -1 Цикл

           Кол = Таб.Колонки[-Сч];

           Если ВладелецФормы.ПолучитьТипыКолонки(Таб, , Кол.Имя) <> Неопределено Тогда
               Таб.ТекущаяКолонка = Кол;
               Прервать;
           КонецЕсли;

       КонецЦикла;
24 Franchiser
 
гуру
11.07.13
13:20
Еще вариант использовать цикл "Пока". При удалении не увеличивать Переменную "номер удаляемой строки". Вообщем вариантов масса.
25 YHVVH
 
11.07.13
13:20
можно вообще без цикла, цикл -зло
26 Asmody
 
11.07.13
13:21
предлагаю суперспособ: сериализовать в XDTO, выгрузить в XML, обработать его как обычный текст — удалить куски, завернуть опять в XDTO и десериализовать.
27 1Сергей
 
11.07.13
13:21
(25) эээ... просвети. Рекурсию тоже будем считать циклом в данном случае
28 Asmody
 
11.07.13
13:22
(26)+ причем, каждое действие реализовать отдельным веб-сервисом
29 Franchiser
 
гуру
11.07.13
13:22
Приведите пример без цикла пжл)
30 Franchiser
 
гуру
11.07.13
13:23
Еще вариант, Запросом получить ТЧ без нужных строк, потом загрузить результат в ТЧ.)
31 Asmody
 
11.07.13
13:23
(29) собрать запросом нужные строки, выгрузить через ТЗ в ТЧ
32 1Сергей
 
11.07.13
13:24
(30) (31) да, вариант без цикла. не поспоришь
33 YHVVH
 
11.07.13
13:24
(27) ТЧ.Загрузить(ТЧ.Выгрузить(Отбор));
34 Franchiser
 
гуру
11.07.13
13:24
(31)я уже догодался) типа табличная модель..
35 1Сергей
 
11.07.13
13:25
(33) ТЧ.Выгрузить(Отбор) ?

сам понял что написал?
36 Franchiser
 
гуру
11.07.13
13:26
(33) гы-гы, полет фантазии?
37 YHVVH
 
11.07.13
13:26
(35) да
38 YHVVH
 
11.07.13
13:27
(35) что тебя удивляет ?
39 1Сергей
 
11.07.13
13:27
(37) Скажи, дружок, какие параметры у метода Табличной части - Выгрузить
40 Franchiser
 
гуру
11.07.13
13:28
Табличная часть (Tabular section)
Выгрузить (Unload)
Вариант синтаксиса: Выгрузить колонки

Синтаксис:

Выгрузить(<Строки>, <Колонки>)
Параметры:

<Строки> (необязательный)

Тип: Массив.
Массив строк для выгрузки. Если не указан, выгружаются все строки табличной части.
<Колонки> (необязательный)

Тип: Строка.
Список колонок для копирования в формате: "Колонка1, Колонка2...". Если список не задан, то будут скопированы все колонки.
41 1Сергей
 
11.07.13
13:29
(40) там есть второй вариант, но он тоже не взлетит
42 YHVVH
 
11.07.13
13:29
(40) а ниже что написано?
43 YHVVH
 
11.07.13
13:30
(41) почему не взлетит?
44 1Сергей
 
11.07.13
13:30
(42) как ты собрался делать отбор по условию НЕ?
45 Franchiser
 
гуру
11.07.13
13:31
(43) Ты хочешь оставить только удаляемые строки что ли?
46 YHVVH
 
11.07.13
13:31
(44) а все понял о чем речь. да, согласен :-))
47 YHVVH
 
11.07.13
13:32
(45) я думал там надо удалить все кроме заданных
48 Franchiser
 
гуру
11.07.13
13:51
Док1 = Док.ПолучитьОбъект();
   ТЧ =  Док1.Товары;
       Запрос = Новый Запрос("ВЫБРАТЬ
                         |    *
                         |Поместить Результат
                         |ИЗ
                         |    &ТЧ КАК ТЧ;
                         |Выбрать * из результат");
                         Запрос.УстановитьПараметр("ТЧ",ТЧ);


   ТЧ.Загрузить(Запрос.Выполнить().Выгрузить());                      
   Док1.Записать();
49 spapin87
 
11.07.13
15:29
(21) Можно еще вопрос по структуре, у меня в Товары нет поля склад, есть только поле МестоХранения и следовательно в структуре должно быть местоХранения, у которого склад = "000000004". Как быть?
50 1Сергей
 
11.07.13
15:32
(49) Вообще, Отбор лучше один раз сделать. примерно так:

Процедура КнопкаВыполнитьНажатие(Кнопка)
   Док = Документы.ИнвентаризацияТоваровНаСкладе.Выбрать();
   Отбор = Новый Структура("МестоХранения", Справочники.Склады.НайтиПоКоду("000000004"));
   Документы.ИнвентаризацияТоваровНаСкладе.Выбрать();
   Пока Док.Следующий() Цикл
       Объект = Док.ПолучитьОбъект();
       НайденныеСтроки = Объект.Товары.НайтиСтроки(Отбор);
       Для Каждого СтрокаКУдалению из НайденныеСтроки Цикл
           Объект.Товары.Удалить(СтрокаКУдалению);
       КонецЦикла;
       Объект.Записать();
   КонецЦикла;
КонецПроцедуры
51 spapin87
 
11.07.13
15:42
(50) Да я так пробовал, при таком условии вообще в цикл не входит
Для Каждого СтрокаКУдалению из НайденныеСтроки Цикл
52 1Сергей
 
11.07.13
15:51
(51) в переменной Отбор всё нормально? Склад твой находит?
53 1Сергей
 
11.07.13
15:52
так, стоп. У тебя много мест хранения с этим складом?
54 spapin87
 
11.07.13
15:59
много поэтому и обработку пишу, чтобы удалить.
Склад находится.
http://s1.ipicture.ru/uploads/20130711/K4zRonid.jpg
http://s1.ipicture.ru/uploads/20130711/2CZPScHs.jpg
55 Franchiser
 
гуру
11.07.13
16:50
(54) Тогда тебе отбор не поможет. На сколько помню в структуре нужно указать только одно значение, а у тебя их несколько д.б.
56 spapin87
 
11.07.13
17:19
Может так попробовать?

 Выбсклад = Справочники.Склады.НайтиПоКоду("000000004");
   Док = Документы.ИнвентаризацияТоваровНаСкладе.Выбрать();
   Пока Док.Следующий() Цикл
       Объект = Док.ПолучитьОбъект();
       КолСтрок = Объект.Товары.Количество();
       Для Сч=1 По КолСтрок Цикл
           НомерСтроки = КолСтрок - Сч;
           ЛСтр = Док.Товары[НомерСтроки];
           Склад = ЛСтр.МестоХранения.Склад.Код;
           Если "000000004" = склад Тогда
               ОбработкаПрерыванияПользователя();
               Сообщить("В " + Док + ";Позиция: " + ЛСтр.Номенклатура + ";находится на складе: " + ЛСтр.МестоХранения.Склад + ";");
               //Док.Товары.Удалить(НомерСтроки);
               КонецЕсли;
           КонецЦикла;                            
           Объект.Записать();
       КонецЦикла;
57 Franchiser
 
гуру
12.07.13
01:20
См пост 20, правильно удалять с конца.
58 Franchiser
 
гуру
12.07.13
01:23
Вроде твой код должен прокатить...
59 Franchiser
 
гуру
12.07.13
01:27
Только переменную номерстроки использовать не советую, во всяком случае в моем коде значение не присваивается ей.