Некорректный обход табличной части

1. Ivan_Abc 24.02.21 07:28 Сейчас в теме
Добрый день уважаемые форумчане! Делаю внешнюю обработку и проблема заключается в следующем: необходимо брать строки ТЧ документа и проверять на заполнение реквизитов Студент или Контрагент. Если хоть один из них заполнен, то пометка на удаление Ложь, если оба реквизита пустые тогда Истина. Код отрабатывает вообще непонятным образом, некоторые документы с 1 строкой зацикливаются по десяткам раз, другие с несколькими строками проходят по циклу как надо, некоторые доки попадают в выборку, но по циклу не проходят от слова совсем, некоторые корректные доки висят после обработки с пометкой на удаление, другие идентичные практически - без пометки. Запрос отрабатывает корректно, данные попадают верные. В общем какая-то дичь, сижу уже второй день, ничего понять не могу. Отладчик гонял на доке с 1 строкой, который падал в лютый цикл по 30 раз, ничего не дало (объективно говоря я не очень с ним дружу). Буду благодарен любой помощи! Код прикладываю ниже:

Процедура КнопкаВыполнитьНажатие(Кнопка)
	
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
	               |	уз_ПриказПоУчебномуЗаведению.Ссылка,
	               |	уз_ПриказПоУчебномуЗаведению.Дата,
	               |	уз_ПриказПоУчебномуЗаведению.Номер,
	               |	уз_ПриказПоУчебномуЗаведению.Список.(
	               |		Контрагент,
	               |		Студент
	               |	)
	               |ИЗ
	               |	Документ.уз_ПриказПоУчебномуЗаведению КАК уз_ПриказПоУчебномуЗаведению
	               |ГДЕ
	               |	уз_ПриказПоУчебномуЗаведению.Дата < ДАТАВРЕМЯ(2017, 1, 1, 0, 0, 0)";
	РезультатЗапроса = Запрос.Выполнить();
	ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
	
	Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
		
		ДокСсылка = ВыборкаДетальныеЗаписи.Ссылка;
		
		Если (ДокСсылка.Список.Количество() > 0) Тогда
			
			ДокОбъект = ДокСсылка.ПолучитьОбъект();
			
			
			Для каждого ТекСтрока Из ДокОбъект.Список Цикл

				Если (НЕ ЗначениеЗаполнено(ТекСтрока.Студент)) И (НЕ ЗначениеЗаполнено(ТекСтрока.Контрагент)) Тогда
					
					ДокОбъектЗапомнить = 0;
					
				ИначеЕсли (ЗначениеЗаполнено(ТекСтрока.Контрагент)) ИЛИ (ЗначениеЗаполнено(ТекСтрока.Студент)) Тогда
					
					ДокОбъектЗапомнить = 1;
			
				КонецЕсли;
			
			КонецЦикла;
			
		Иначе
			
			ДокОбъектЗапомнить = 0;
			
		КонецЕсли;
		
		Если ДокОбъектЗапомнить = 0 Тогда
			
			ДокОбъект.УстановитьПометкуУдаления(Истина);
			ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
			Сообщить("Установлена пометка удаления на документ №: " + ДокОбъект.Номер + " от " + Строка(ДокОбъект.Дата));
			
		ИначеЕсли ДокОбъектЗапомнить = 1 Тогда
			
			ДокОбъект.УстановитьПометкуУдаления(Ложь);
			ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
			Сообщить("Снята пометка удаления с документа №: " + ДокОбъект.Номер + " от " + Строка(ДокОбъект.Дата));
			
		КонецЕсли;
			
	КонецЦикла;

	Сообщить("Обработка завершена!")

КонецПроцедуры
Показать
По теме из базы знаний
Найденные решения
16. ДмитрийС 24.02.21 12:03 Сейчас в теме
(15) Тогда вот так)) Сложно писать запрос не имея под рукой объектов)

ВЫБРАТЬ
	уз_ПриказПоУчебномуЗаведению.Ссылка КАК уз_ПриказПоУчебномуЗаведению,
	уз_ПриказПоУчебномуЗаведению.ПометкаУдаления КАК ПометкаУдаления
ПОМЕСТИТЬ ДокументыПриказ
ИЗ
	Документ.уз_ПриказПоУчебномуЗаведению КАК уз_ПриказПоУчебномуЗаведению
ГДЕ
	уз_ПриказПоУчебномуЗаведению.Ссылка.Дата < ДАТАВРЕМЯ(2017, 1, 1, 0, 0, 0)
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ДокументыПриказ.уз_ПриказПоУчебномуЗаведению КАК уз_ПриказПоУчебномуЗаведению,
	МАКСИМУМ(ВЫБОР
			КОГДА ЕСТЬNULL(уз_ПриказПоУчебномуЗаведениюСписок.Студент, ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)) = ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)
					И ЕСТЬNULL(уз_ПриказПоУчебномуЗаведениюСписок.Контрагент, ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)) = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
				ТОГДА ИСТИНА
			ИНАЧЕ ЛОЖЬ
		КОНЕЦ) КАК УстановитьПометкуУдаления,
	ДокументыПриказ.ПометкаУдаления
ПОМЕСТИТЬ ДокументыПриказСДаннымиПоТЧ
ИЗ
	ДокументыПриказ КАК ДокументыПриказ
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.уз_ПриказПоУчебномуЗаведению.Список КАК уз_ПриказПоУчебномуЗаведениюСписок
		ПО ДокументыПриказ.уз_ПриказПоУчебномуЗаведению = уз_ПриказПоУчебномуЗаведениюСписок.Ссылка

СГРУППИРОВАТЬ ПО
	ДокументыПриказ.уз_ПриказПоУчебномуЗаведению,
	ДокументыПриказ.ПометкаУдаления
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ДокументыПриказСДаннымиПоТЧ.уз_ПриказПоУчебномуЗаведению,
	ДокументыПриказСДаннымиПоТЧ.УстановитьПометкуУдаления,
	ДокументыПриказСДаннымиПоТЧ.ПометкаУдаления
ИЗ
	ДокументыПриказСДаннымиПоТЧ КАК ДокументыПриказСДаннымиПоТЧ
ГДЕ
	НЕ ДокументыПриказСДаннымиПоТЧ.УстановитьПометкуУдаления = ДокументыПриказСДаннымиПоТЧ.ПометкаУдаления
Показать
Ivan_Abc; +1 Ответить
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. ZergKRSK 129 24.02.21 07:43 Сейчас в теме
(1) вы с какой целью в запрос включаете ТЧ документа, если потом ТЧ перебираете уже через объект документа?
Ivan_Abc; +1 Ответить
3. Ivan_Abc 24.02.21 07:48 Сейчас в теме
(2) забыл убрать из запроса
ну в принципе это на работоспособность отчета не влияет
4. glek 119 24.02.21 08:17 Сейчас в теме
Ну а что? Логично наверное работает: если в первой строке документа у вас не заполнено ни одно поле, а в последней - хоть одно, то ваш алгоритм снимет пометку удаления.
7. Ivan_Abc 24.02.21 08:43 Сейчас в теме
(4) в том то и дело, что доки, которые с 1 заполненной строкой тоже висят с пометкой удаления
а так как Вы написали так и надо, что если хоть что-то заполнена, хоть одна строка, то пометка должна быть снята
11. glek 119 24.02.21 09:03 Сейчас в теме
(7)Так если последняя строка будет не заполнена, то документ пометится на удаление.
Ivan_Abc; +1 Ответить
12. Ivan_Abc 24.02.21 09:11 Сейчас в теме
(11) ну это да, тут не обратил внимание, спасибо большое, исправил
5. ДмитрийС 24.02.21 08:37 Сейчас в теме
А чем не устраивает такой запрос?

ВЫБРАТЬ
	уз_ПриказПоУчебномуЗаведениюСписок.Ссылка КАК Ссылка,
	МАКСИМУМ(ВЫБОР
			КОГДА уз_ПриказПоУчебномуЗаведениюСписок.Студент = ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)
					И уз_ПриказПоУчебномуЗаведениюСписок.Контрагент = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
				ТОГДА ИСТИНА
			ИНАЧЕ ЛОЖЬ
		КОНЕЦ) КАК УстановитьПометкуУдаления
ИЗ
	Документ.уз_ПриказПоУчебномуЗаведению.Список КАК уз_ПриказПоУчебномуЗаведениюСписок
ГДЕ
	уз_ПриказПоУчебномуЗаведениюСписок.Ссылка.Дата < ДАТАВРЕМЯ(2017, 1, 1, 0, 0, 0)

СГРУППИРОВАТЬ ПО
	уз_ПриказПоУчебномуЗаведениюСписок.Ссылка

УПОРЯДОЧИТЬ ПО
	Ссылка
АВТОУПОРЯДОЧИВАНИЕ
Показать


При условии конечно, что Студент и Контрагент у вас реквизиты не составного типа, и примерно того типа, что я указал (можно и поменять).

Далее просто перебираете результат запроса и на основании "УстановитьПометкуУдаления" устанавливаете или снимаете пометку на удаление.
6. retr0 24.02.21 08:40 Сейчас в теме
Ну во-первых, я бы все это выбрал запросом. Во-вторых результат выборки обошел бы в цикле, я бы вернул только документы которые нужны для того чтобы установить флаг удаления. И все. Пишешь запрос к ТЧ документа. Устанавливаешь параметры отбора. Делов на 3 копейки.

ВЫБРАТЬ
                   |    уз_ПриказПоУчебномуЗаведению.Ссылка КАК Ссылка
                   |ИЗ
                   |    уз_ПриказПоУчебномуЗаведению.Список КАК уз_ПриказПоУчебномуЗаведению
                   |ГДЕ
                   |    уз_ПриказПоУчебномуЗаведению.Ссылка.Дата < ДАТАВРЕМЯ(2017, 1, 1, 0, 0, 0)
                   |    И уз_ПриказПоУчебномуЗаведению.Студент = ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)
                   |    И уз_ПриказПоУчебномуЗаведению.Контрагент = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)";
8. Ivan_Abc 24.02.21 08:46 Сейчас в теме
(6) в любом случае работать со всеми доками придется, т.к. часть доков, которые нужны, помечены на удаление
9. ДмитрийС 24.02.21 08:50 Сейчас в теме
(8) Так в мой запрос можно расширить и сделать еще сравнение текущей пометки на удаление с той, которую предлагает запрос. И обрабатывать только те документы, у которых несовпадение)
10. Ivan_Abc 24.02.21 08:52 Сейчас в теме
(9) я вот как раз сейчас с Вашим запросом копаюсь)
13. retr0 24.02.21 09:27 Сейчас в теме
(10) К чему эти усложнения? Вариант предложенный (9) уже по своей сути перегружен не нужными сравнениями, задача здесь примитивная.
14. ДмитрийС 24.02.21 09:34 Сейчас в теме
(13) Вы считаете, что проще перебор строк сделать? И быстрее? В моем запросе минимум необходимого. Просьба указать не перегруженность, может что-то и не учел)

Upd. Автор же еще хочет предусмотреть ситуацию, когда документ помечен на удаление, а пометка должна быть снята.
15. Alvis44 24.02.21 11:16 Сейчас в теме
(14) Мне кажется у ваших обоих запросов есть недочёт. У автора есть ветка в условии
Если (ДокСсылка.Список.Количество() > 0) Тогда

Где при условии, что таб часть пустая, то ставится пометка на удаление. В ваших запросах будет потеря этих доков.
Это так, чтобы автор если что копировал внимательно)
16. ДмитрийС 24.02.21 12:03 Сейчас в теме
(15) Тогда вот так)) Сложно писать запрос не имея под рукой объектов)

ВЫБРАТЬ
	уз_ПриказПоУчебномуЗаведению.Ссылка КАК уз_ПриказПоУчебномуЗаведению,
	уз_ПриказПоУчебномуЗаведению.ПометкаУдаления КАК ПометкаУдаления
ПОМЕСТИТЬ ДокументыПриказ
ИЗ
	Документ.уз_ПриказПоУчебномуЗаведению КАК уз_ПриказПоУчебномуЗаведению
ГДЕ
	уз_ПриказПоУчебномуЗаведению.Ссылка.Дата < ДАТАВРЕМЯ(2017, 1, 1, 0, 0, 0)
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ДокументыПриказ.уз_ПриказПоУчебномуЗаведению КАК уз_ПриказПоУчебномуЗаведению,
	МАКСИМУМ(ВЫБОР
			КОГДА ЕСТЬNULL(уз_ПриказПоУчебномуЗаведениюСписок.Студент, ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)) = ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)
					И ЕСТЬNULL(уз_ПриказПоУчебномуЗаведениюСписок.Контрагент, ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)) = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
				ТОГДА ИСТИНА
			ИНАЧЕ ЛОЖЬ
		КОНЕЦ) КАК УстановитьПометкуУдаления,
	ДокументыПриказ.ПометкаУдаления
ПОМЕСТИТЬ ДокументыПриказСДаннымиПоТЧ
ИЗ
	ДокументыПриказ КАК ДокументыПриказ
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.уз_ПриказПоУчебномуЗаведению.Список КАК уз_ПриказПоУчебномуЗаведениюСписок
		ПО ДокументыПриказ.уз_ПриказПоУчебномуЗаведению = уз_ПриказПоУчебномуЗаведениюСписок.Ссылка

СГРУППИРОВАТЬ ПО
	ДокументыПриказ.уз_ПриказПоУчебномуЗаведению,
	ДокументыПриказ.ПометкаУдаления
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ДокументыПриказСДаннымиПоТЧ.уз_ПриказПоУчебномуЗаведению,
	ДокументыПриказСДаннымиПоТЧ.УстановитьПометкуУдаления,
	ДокументыПриказСДаннымиПоТЧ.ПометкаУдаления
ИЗ
	ДокументыПриказСДаннымиПоТЧ КАК ДокументыПриказСДаннымиПоТЧ
ГДЕ
	НЕ ДокументыПриказСДаннымиПоТЧ.УстановитьПометкуУдаления = ДокументыПриказСДаннымиПоТЧ.ПометкаУдаления
Показать
Ivan_Abc; +1 Ответить
17. Ivan_Abc 02.03.21 06:42 Сейчас в теме
(16)
ВЫБРАТЬ
уз_ПриказПоУчебномуЗаведению.Ссылка КАК уз_ПриказПоУчебномуЗаведению,
уз_ПриказПоУчебномуЗаведению.ПометкаУдаления КАК ПометкаУдаления
ПОМЕСТИТЬ ДокументыПриказ
ИЗ
Документ.уз_ПриказПоУчебномуЗаведению КАК уз_ПриказПоУчебномуЗаведению
ГДЕ
уз_ПриказПоУчебномуЗаведению.Ссылка.Дата < ДАТАВРЕМЯ(2017, 1, 1, 0, 0, 0)
;

////////////////////////////////////////////////////////////­­////////////////////
ВЫБРАТЬ
ДокументыПриказ.уз_ПриказПоУчебномуЗаведению КАК уз_ПриказПоУчебномуЗаведению,
МАКСИМУМ(ВЫБОР
КОГДА ЕСТЬNULL(уз_ПриказПоУчебномуЗаведениюСписок.Студент, ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)) = ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)
И ЕСТЬNULL(уз_ПриказПоУчебномуЗаведениюСписок.Контрагент, ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)) = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
ТОГДА ИСТИНА
ИНАЧЕ ЛОЖЬ
КОНЕЦ) КАК УстановитьПометкуУдаления,
ДокументыПриказ.ПометкаУдаления
ПОМЕСТИТЬ ДокументыПриказСДаннымиПоТЧ
ИЗ
ДокументыПриказ КАК ДокументыПриказ
ЛЕВОЕ СОЕДИНЕНИЕ Документ.уз_ПриказПоУчебномуЗаведению.Список КАК уз_ПриказПоУчебномуЗаведениюСписок
ПО ДокументыПриказ.уз_ПриказПоУчебномуЗаведению = уз_ПриказПоУчебномуЗаведениюСписок.Ссылка

СГРУППИРОВАТЬ ПО
ДокументыПриказ.уз_ПриказПоУчебномуЗаведению,
ДокументыПриказ.ПометкаУдаления
;

////////////////////////////////////////////////////////////­­////////////////////
ВЫБРАТЬ
ДокументыПриказСДаннымиПоТЧ.уз_ПриказПоУчебномуЗаведению,
ДокументыПриказСДаннымиПоТЧ.УстановитьПометкуУдаления,
ДокументыПриказСДаннымиПоТЧ.ПометкаУдаления
ИЗ
ДокументыПриказСДаннымиПоТЧ КАК ДокументыПриказСДаннымиПоТЧ
ГДЕ
НЕ ДокументыПриказСДаннымиПоТЧ.УстановитьПометкуУдаления = ДокументыПриказСДаннымиПоТЧ.ПометкаУдаления
Показать


Одно уточнение, каким образом мне сейчас работать с пометкой удаление у док-тов? Выборка.Ссылка и ПолучитьОбъект не работают
Заранее большое спасибо за ответ!
18. ДмитрийС 02.03.21 12:06 Сейчас в теме
(17) Судя по тексту запроса
ТекущийДокумент = Выборка.уз_ПриказПоУчебномуЗаведению.ПолучитьОбъект();
ТекущийДокумент.УстановитьПометкуУдаления(Выборка.УстановитьПометкуУдаления)
Ivan_Abc; +1 Ответить
19. Ivan_Abc 03.03.21 06:44 Сейчас в теме
(18) Большое спасибо! Всё работает!
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот