Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

Вопрос по удалению строк документа по номеру строки

Вопрос по удалению строк документа по номеру строки
Я
   asder117
 
25.09.20 - 09:06
Коллеги доброе время суток..прошу не пинать сразу..просто на вроде легком вопросе встал в ступор.
Есть документ в 4000 строк, есть таблица с номерами строк которые надо удалить
На первый взгляд приходит такое:
    для каждого СтрокаДляУдаления из СтрокиВДокументах цикл
        если СтрокаДляУдаления.СтрокаТН = "" тогда
            продолжить
        КонецЕсли;
////++++Тестово удалим строки
ОбъектДок = ТН.ПолучитьОбъект();
СтруктураДляПоиска = Новый Структура("НомерСтроки", СтрокаДляУдаления.СтрокаТН);
ТабличнаяЧастьДок = ОбъектДок.Материалы;
//Получаем список строк соответсвтвующих отбору, и перебором удаляем.
МассивПустыхСтрок = ТабличнаяЧастьДок.НайтиСтроки(СтруктураДляПоиска);
Для каждого Строка Из МассивПустыхСтрок Цикл
    попытка
    ТабличнаяЧастьДок.Удалить(Строка);
    Сообщить("удалена строка " + СтрокаДляУдаления.СтрокаТН)
исключение
    
    конецпопытки
КонецЦикла;
Но не тут то было после удаления номер строки поменяется...тут и вопрос как скопом удалить необходимые 1000 строк в доке...Спасибо заранее
   MouHacTaBHuk
 
1 - 25.09.20 - 09:11
(0) удаляй просто обратным циклом, от 4000 до 1
   Fish
 
2 - 25.09.20 - 09:11
(0) Так всё верно у тебя написано, удалятся нужные строки.
   Fish
 
3 - 25.09.20 - 09:13
+(2) только вот цикл по удалению надо вынести за рамки первого цикла. А он у тебя зачем-то внутри.
   asder117
 
4 - 25.09.20 - 09:13
(2) Когда удаляются строки из табличной части нумерация сдвигается и удаляться могут не те строки
   asder117
 
5 - 25.09.20 - 09:14
(3) В смысле...хотя я понял можно номера строк загнать в массив и потом обратным перебором грохнуть строки..только вспомнит как с конца начать перебор
   Fish
 
6 - 25.09.20 - 09:14
(4) Первым циклом ты отбираешь все строки для удаления в массив строк. А уже потом (а не внутри этого цикла, как у тебя) ты удаляешь эти строки.
   Fish
 
7 - 25.09.20 - 09:15
(5) Не номера строк. Метод НайтиСтроки вернут тебе Массив самих строки. И при удалении уже пофиг на изменение номера - удалятся только отобранные строки.
   asder117
 
8 - 25.09.20 - 09:18
(6)// Вставить содержимое обработчика.

    для каждого СтрокаДляУдаления из СтрокиВДокументах цикл
        если СтрокаДляУдаления.СтрокаТН = "" тогда
            продолжить
        КонецЕсли;
////++++Тестово удалим строки

ОбъектДок = ТН.ПолучитьОбъект(); 
СтруктураДляПоиска = Новый Структура("НомерСтроки", СтрокаДляУдаления.СтрокаТН); 
ТабличнаяЧастьДок = ОбъектДок.Материалы; 
КонецЦикла;
//Получаем список строк соответсвтвующих отбору, и перебором удаляем.

МассивПустыхСтрок = ТабличнаяЧастьДок.НайтиСтроки(СтруктураДляПоиска); 
Для каждого Строка Из МассивПустыхСтрок Цикл 
    попытка
    ТабличнаяЧастьДок.Удалить(Строка); 
    Сообщить("удалена строка " + СтрокаДляУдаления.СтрокаТН)
исключение
    
    конецпопытки
КонецЦикла; 
////----

Типа такого получается? Только мне кажется структура это не то что надо может в массив лучше
   asder117
 
9 - 25.09.20 - 09:18
(7) Я это понял тут и застопорился
   Fish
 
10 - 25.09.20 - 09:19
(8) Для начала скажи, что такое у тебя СтрокиВДокументах и что такое ТН?
   Fish
 
11 - 25.09.20 - 09:21
(8) Так не сработает, ты удалишь только строки по последнему значению СтрокаТН.
   asder117
 
12 - 25.09.20 - 09:21
(10) СтрокиВДокументах - таблица номеров строк документа ТН Это документ требования накладня
   asder117
 
13 - 25.09.20 - 09:23
(11) Вот и я о томже тогда может лучше в первом цикле строки загнать в массив точнее номера а потом массив загнать в НайтиСтрои и удалить
   hhhh
 
14 - 25.09.20 - 09:26
(13) вот номера точно не нужно загонять. Сами строки загони.
   Fish
 
15 - 25.09.20 - 09:27
(12) Тогда делай как-то так:
МассивДляУдаления = Новый Массив;
 для каждого СтрокаДляУдаления из СтрокиВДокументах цикл

Если ЗначениеЗаполнено(СтрокаДляУдаления.СтрокаТН) Тогда
СтрокаДляУдаления = ТН.Материалы.Найти(СтрокаДляУдаления.СтрокаТН,"НомерСтроки");
Если СтрокаДляУдаления <> Неопределено Тогда
МассивДляУдаления.Добавить(СтрокаДляУдаления);
КонецЕсли;
КонецЕсли;

ОбъектДок = ТН.ПолучитьОбъект();
Для каждого Строка Из МассивДляУдаленияЦикл 
    ОбъектДок.Материалы.Удалить(Строка); 
исключение
   Fish
 
16 - 25.09.20 - 09:28
+(15) Забыл конецЦикла перед получитьОбъект. И вместо исключения тоже конецЦикла.
   Fish
 
17 - 25.09.20 - 09:30
А получать объект в цикле это нехорошо, раз у тебя всего один документ.
   asder117
 
18 - 25.09.20 - 09:31
(14) (15) (16) Спасибо я к этому тоже уже пришел
ЗначениеЗаполнено(СтрокаДляУдаления.СтрокаТН) главное чтобы хорошо сработал с пустым строковым значением 
(17) Знаю просто уже заработался
   Fedor-1971
 
19 - 25.09.20 - 09:32
(13) погоди шашкой махать, Вот это работа внутри ОДНОГО документа
ОбъектДок = ТН.ПолучитьОбъект(); - получили ОБЪЕКТ ТН, т.е. сам документ
ТабличнаяЧастьДок = ОбъектДок.Материалы; 

Вот ТУТ Перебирай циклом свои условия удаления
Для каждого текУсловие из МассивУсловийОчистки цикл

  СтруктураДляПоиска = Новый Структура("НомерСтроки", !!!Условие!!!!); - настроили поиск
  МассивПустыхСтрок = ТабличнаяЧастьДок.НайтиСтроки(СтруктураДляПоиска); - получил выборку СТРОК, не омеров!!!

  Для каждого СтрокаТЧ Из МассивПустыхСтрок Цикл 
    Сообщить("удалена строка " + СтрокаТЧ.????); , например, СтрокаТЧ.Номенклатура
    ТабличнаяЧастьДок.Удалить(СтрокаТЧ); 
   КонецЦикла; 
КонецЦикла;

   asder117
 
20 - 25.09.20 - 09:37
(19) Все номера загоняем в МассивУсловийОчистки получается и потом его перебираем
"СтруктураДляПоиска = Новый Структура("НомерСтроки", !!!Условие!!!!); - настроили поиск
  МассивПустыхСтрок = ТабличнаяЧастьДок.НайтиСтроки(СтруктураДляПоиска); - получил выборку СТРОК, не омеров!!!
"
Тут мы ищем одну строку по номеру и загоняем ее в массив и получается массив обновляется а не добавляется и я так думаю придем к удалению только последней строки
   asder117
 
21 - 25.09.20 - 09:39
(19)  СтруктураДляПоиска = Новый Структура("НомерСтроки", !!!Условие!!!!); - настроили поиск После удаления номер строки поменяется и мы получается найдем следующую строку...
Остальное все мне понятно
   hhhh
 
22 - 25.09.20 - 09:44
(19) Для каждого текУсловие из МассивУсловийОчистки цикл
  СтруктураДляПоиска = Новый Структура("НомерСтроки", !!!Условие!!!!); - настроили поиск
  МассивПустыхСтрок = ТабличнаяЧастьДок.НайтиСтроки(СтруктураДляПоиска); - получил выборку СТРОК, не омеров!!!

КонецЦикла;

  Для каждого СтрокаТЧ Из МассивПустыхСтрок Цикл 
    Сообщить("удалена строка " + СтрокаТЧ.????); , например, СтрокаТЧ.Номенклатура
    ТабличнаяЧастьДок.Удалить(СтрокаТЧ); 
   КонецЦикла;
   Fedor-1971
 
23 - 25.09.20 - 09:48
(20) Погоди, это кусок твоего кода я не знаю ни количества условий, ни их состава.
НайтиСтроки гонять для поиска по номеру одной строки для удаления как-то жирно

В (15) тебе предложили перебрать ТЧ, каждую (!!!) строку проверить на Все (!!!) нужные тебе условия и сформировать массив СтрокДляУдаления.

Дальше скопом просто удаляем выбранные строки

Так более эффективно, чем гонять НайтиСтроки
   asder117
 
24 - 25.09.20 - 10:01
(15) Не взлетело
   Saari
 
25 - 25.09.20 - 10:02
Готовое решение (проверил, работает):

ДокОбъект = ТН.ПолучитьОбъект();
инд = ДокОбъект.Материалы.Количество();
Пока инд > 0 Цикл
  СтруктураДляПоиска = Новый Структура("СтрокаТН", инд);
  Отбор = СтрокиВДокументах.НайтиСтроки(СтруктураДляПоиска);
  Если Отбор.Количество() > 0 Тогда
    СтрокаДляУдаления = ТН.Материалы.Найти(инд, "НомерСтроки");
    Если СтрокаДляУдаления <> Неопределено Тогда
        ДокОбъект.Материалы.Удалить(СтрокаДляУдаления);
    КонецЕсли;
  КонецЕсли;
  инд = инд - 1;    
КонецЦикла;
    
ДокОбъект.Записать();
   asder117
 
26 - 25.09.20 - 10:03
(23) 15 не взлетел..строки остались как стояли
   Saari
 
27 - 25.09.20 - 10:03
Думаю, теперь взлетит.
   asder117
 
28 - 25.09.20 - 10:04
(25) Я тоже думаю так как передала практически таккже с индексами
   Saari
 
29 - 25.09.20 - 10:05
(28) проверяй и скажи результат.
   Fish
 
30 - 25.09.20 - 10:07
(26) Так после удаления надо документ записать.
 
 Рекламное место пустует
   asder117
 
31 - 25.09.20 - 10:09
(25) (29) Я его ткрываю для просмотра без записи и записываю после проверки...
Сейчас попробую
   asder117
 
32 - 25.09.20 - 10:10
(30) ДокОбъект.Записать();
ФормаДок = ДокОбъект.ПолучитьФорму("ФормаДокумента");
ФормаДок.Открыть();
   asder117
 
33 - 25.09.20 - 10:12
(32) было 3162 строки и осталось
   asder117
 
34 - 25.09.20 - 10:13
(25) 3162 строки было и остались....ничего не понимаю
   Fish
 
35 - 25.09.20 - 10:14
(34) Посмотри в отладчике, может, у тебя строки для удаления не ищутся.
   Bigbro
 
36 - 25.09.20 - 10:15
34 ответа жесть.
второй список с номерами для удаления отсортируй по номерам.
проходишь по этому списку от большего к меньшему удаляешь строку по номеру. все!
   asder117
 
37 - 25.09.20 - 10:17
(35) ок
   Saari
 
38 - 25.09.20 - 10:19
(34) Я проверил этот код. Работает. И сортировать ничего не надо.
Покажи свой код полностью.
   Fish
 
39 - 25.09.20 - 10:19
(36) Мы тут не ищем лёгких путей, а ты пришёл и всё упростил :))
   asder117
 
40 - 25.09.20 - 10:21
ДокОбъект = ТН.ПолучитьОбъект();
инд = ДокОбъект.Материалы.Количество();
Пока инд > 0 Цикл
  СтруктураДляПоиска = Новый Структура("СтрокаТН", инд);
  Отбор = СтрокиВДокументах.НайтиСтроки(СтруктураДляПоиска);
  Если Отбор.Количество() > 0 Тогда
    СтрокаДляУдаления = ТН.Материалы.Найти(инд, "НомерСтроки");
    Если СтрокаДляУдаления <> Неопределено Тогда
        ДокОбъект.Материалы.Удалить(СтрокаДляУдаления);
    КонецЕсли;
  КонецЕсли;
  инд = инд - 1;    
КонецЦикла;
//ФормаДок = ДокОбъект.ПолучитьФорму("ФормаДокумента");

//ФормаДок.Открыть();
    
ДокОбъект.Записать();
ФормаДок = ДокОбъект.ПолучитьФорму("ФормаДокумента");
ФормаДок.Открыть(); (38)
   Saari
 
41 - 25.09.20 - 10:23
ТН должна содержать ссылку на документ. Это так?
   asder117
 
42 - 25.09.20 - 10:23
(41) Да само собой
   Saari
 
43 - 25.09.20 - 10:24
(42) только что повторил. Все работает, форма открывается с уже удаленными строками.
   Saari
 
44 - 25.09.20 - 10:26
Стоп!
Замени СтрокаДляУдаления = ТН.Материалы.Найти(инд, "НомерСтроки");
на строку СтрокаДляУдаления = ДокОбъект.Найти(инд, "НомерСтроки");
   Saari
 
45 - 25.09.20 - 10:26
на строку СтрокаДляУдаления = ДокОбъект.Материалы.Найти(инд, "НомерСтроки");
   Saari
 
46 - 25.09.20 - 10:27
(45) правильно.
   Saari
 
47 - 25.09.20 - 10:30
(42) Как там результат?
   asder117
 
48 - 25.09.20 - 10:32
(47) Похоже я понял в чем причина...неразрывный пробел в номере похоже и тут и косячит..
   Saari
 
49 - 25.09.20 - 10:33
(48) но строку переправь на эту: СтрокаДляУдаления = ДокОбъект.Материалы.Найти(инд, "НомерСтроки");
значения в таблице с номерами строк должны быть числовые.
   asder117
 
50 - 25.09.20 - 10:35
(47) Стоп а СтрокаТН Как попадает в структуру...мы похоже цикл забыли по табличной части где указаны номера строк
   Fish
 
51 - 25.09.20 - 10:37
(48) Номер строки должен быть числом.
   asder117
 
52 - 25.09.20 - 10:37
для каждого СтрокаДляУдаления из СтрокиВДокументах цикл
        если СтрокаДляУдаления.СтрокаТН = "" тогда
            продолжить
        КонецЕсли;
Конеццикла
Я этот кусок же вставлял чтобы он у меня проходил по строкам где есть зополнен номерСтрокиТН
   asder117
 
53 - 25.09.20 - 10:37
(51) Да понял я
   Saari
 
54 - 25.09.20 - 10:41
(48) Напиши проверку для таблицы номеров:
Для Каждого Стр из СтрокиВДокументах Цикл
   Стр.СтрокаТН = СтрЗаменить(Стр.СтрокаТН, Символы.НПП, "");
   Стр.СтрокаТН = Число(Стр.СтрокаТН);
КонецЦикла;
Уберутся пробелы в номерах и превратятся в числа.
   asder117
 
55 - 25.09.20 - 10:42
(54) Я переделал все норм теперь числа на в (49) у тебя в инд попадает не тот номер строки и таб части а тот индекса цикла из перебора
   Saari
 
56 - 25.09.20 - 10:44
ну а теперь работает?
   Saari
 
57 - 25.09.20 - 10:46
(55) да, но по инд я ищу номер строки в таблице с номерами строк. и если он есть, то удаляю строку в документе по этому номеру.
   asder117
 
58 - 25.09.20 - 10:47
(56) В инд не попадают мои строки
   Saari
 
59 - 25.09.20 - 10:48
(58) С чего вдруг они не попадут?
Они не попадут только в одном случае: если номер строки в таблице больше количества строк в документе.
   Saari
 
60 - 25.09.20 - 10:48
(58) ну а теперь взлетело?
 
 Рекламное место пустует
   Saari
 
61 - 25.09.20 - 10:55
Предлагаю еще один вариант (попроще):

СтрокиВДокументах.Сортировать("СтрокаТН Убыв");

ДокОбъект = ТН.ПолучитьОбъект();
КоличествоСтрокДокумента = ДокОбъект.Материалы.Количество();    
Для Каждого Стр Из СтрокиВДокументах Цикл
  Если Стр.СтрокаТН <= КоличествоСтрокДокумента Тогда
    СтрокаДляУдаления = ДокОбъект.Материалы.Найти(Стр.СтрокаТН, "НомерСтроки");
    Если СтрокаДляУдаления <> Неопределено Тогда
           ДокОбъект.Материалы.Удалить(СтрокаДляУдаления);
    КонецЕсли;
  КонецЕсли;
КонецЦикла;
    
ДокОбъект.Записать();
ФормаДок = ДокОбъект.ПолучитьФорму("ФормаДокумента");
ФормаДок.Открыть();
   Saari
 
62 - 25.09.20 - 10:55
этот вариант вообще без инд
   Saari
 
63 - 25.09.20 - 11:01
Вы где?
   asder117
 
64 - 25.09.20 - 11:04
(63) тут проверяю
   asder117
 
65 - 25.09.20 - 11:08
(63) взлетело...у менгя табчасть изначально не видел..через док.табчасть..все норм смотрим..
   asder117
 
66 - 25.09.20 - 11:09
(62) Спасибо большое..общими трудами свояли...
   Saari
 
67 - 25.09.20 - 11:11
(65) так в моих примерах везде док.табчасть написано.
   Garykom
 
68 - 25.09.20 - 11:12
(0) Запомни! Копирование быстрее удаления! В 99% случаев.

Короче создаешь новый документ и переносишь туда только нужные строки ))
   asder117
 
69 - 25.09.20 - 11:51
(68) отчасти соглашусь..и этим пользуюусь..такой механизм у меня есть..просто не есть хорошо плодить документы
   Fedor-1971
 
70 - 25.09.20 - 12:04
(69) Это трындец товарищи присяжные заседатели.
выремТЗ = ДокОбъект.Материалы.Выгрузить();
ДокОбъект.Материалы.Очистить();
Для каждого текСтрока из времТЗ цикл
  Если ..Проверяем условие заполненности .. тогда
     нов = ДокОбъект.Материалы.Добавить();
     ЗаполнитьЗначенияСвойств(нов, текСтрока);
  КонецЕсли;
КонецЦикла;

тут, документ записать


т.е. просто пройти через временную таблицу значений не вариант?
   asder117
 
71 - 25.09.20 - 12:10
(70) еще один вариант решения вопроса...сколько программеров столько мнений


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.