1С перейти к строке по номеру

25 Августа 2019 Рассмотрен вопрос осуществления проверки на наличие дублирующихся строк в табличных частях, предложен альтернативный вариант. Думаю, каждый программист рано или поздно сталкивался с подобной задачей: как реализовать проверку на наличие дублирующихся строк в табличных частях. Кому-то просто нужно проверить: есть, или нет, дубли. Кому-то нужно известить пользователя, и сообщить ему номера строк с дублями. Это вопросы будут рассмотрены в данной статье. Но давайте сразу определимся с терминологией: поля, по которым будет осуществляться контроль, назовем «ключевые».
Итак, предположим, что у нас стоит задача проверить наличие дублей строк табличной части по ключевым полям. Пусть это будет документ «Реализация товаров, услуг», дубли строк мы будем искать в табличной части «Товары», а в качестве ключевых полей будем использовать следующие реквизиты табличной части: Качество, Номенклатура, Склад, СерияНоменклатуры и ХарактеристикаНоменклатуры.
Рассмотрим следующие ситуации:
1) Проверка на наличие дублирующихся строк на уровне есть/нет.
Реализация ее будет выглядеть следующим образом:
Запрос = Новый Запрос;
Запрос.УстановитьПараметр(«Ссылка», Ссылка);
Запрос.Текст =
«ВЫБРАТЬ
| ТабЧасть.Качество,
| ТабЧасть.Номенклатура,
| ТабЧасть.СерияНоменклатуры,
| ТабЧасть.Склад,
| ТабЧасть.ХарактеристикаНоменклатуры,
| КОЛИЧЕСТВО(ТабЧасть.НомерСтроки) КАК КоличествоДублей
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК ТабЧасть
|ГДЕ
| ТабЧасть.Ссылка = &Ссылка
|
|СГРУППИРОВАТЬ ПО
| ТабЧасть.Качество,
| ТабЧасть.Номенклатура,
| ТабЧасть.СерияНоменклатуры,
| ТабЧасть.Склад,
| ТабЧасть.ХарактеристикаНоменклатуры
|
|ИМЕЮЩИЕ
| КОЛИЧЕСТВО(ТабЧасть.НомерСтроки) > 1″;
РезЗапроса = Запрос.Выполнить();
Если Не РезЗапроса.Пустой() Тогда
Сообщить(«Имеются дубли строк!!!»);
КонецЕсли;
Здесь все достаточно просто. Обращаемся к данным табличной части документа, группируем по ключевым полям с использование агрегатной функции для подсчета количества номеров строк. Накладываем условие по вычисленному значению агрегатной функции. Все.

2) Классика жанра. Выведем в сообщении пользователю номера всех тех строк табличной части, которые являются дублями.

Запрос = Новый Запрос;

Запрос.УстановитьПараметр(«Ссылка», Ссылка);

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

| (ВЫБРАТЬ
| ВТ.Качество,
| ВТ.Номенклатура,
| ВТ.СерияНоменклатуры,
| ВТ.Склад,
| ВТ.ХарактеристикаНоменклатуры
| ИЗ
| ВТ_ТабЧасть КАК ВТ
| СГРУППИРОВАТЬ ПО
| ВТ.Качество,
| ВТ.Номенклатура,
| ВТ.СерияНоменклатуры,
| ВТ.Склад,
| ВТ.ХарактеристикаНоменклатуры
| ИМЕЮЩИЕ
| КОЛИЧЕСТВО(ВТ.НомерСтроки) > 1)
|
|УПОРЯДОЧИТЬ ПО
| НомерСтроки
|ИТОГИ ПО
| Качество,
| Номенклатура,
| СерияНоменклатуры,
| Склад»;
РезЗапроса = Запрос.Выполнить();
Если Не РезЗапроса.Пустой() Тогда
Выб_Качество = РезЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_Качество.Следующий() Цикл
Выб_Номенклатура = Выб_Качество.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_Номенклатура.Следующий() Цикл
Выб_СерияНоменклатуры = Выб_Номенклатура.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_СерияНоменклатуры.Следующий() Цикл
Выб_Склад = Выб_СерияНоменклатуры.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_Склад.Следующий() Цикл
Выборка = Выб_Склад.Выбрать();
ТекстСообщения = «»;
Пока Выборка.Следующий() Цикл
ТекстСообщения = ТекстСообщения + ?(ПустаяСтрока(ТекстСообщения), «», «, «) + Выборка.НомерСтроки;
КонецЦикла;
ТекстСообщения = «Обнаружено дублирование строк: » + ТекстСообщения; Сообщить(ТекстСообщения);
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецЦикла;

КонецЕсли

Здесь все тоже не слишком сложно. Обратились к данным табличной части документа, поместили их во временную таблицу. Далее работаем со временной таблицей. Обращаемся к ней, отбираем те данные, по которым есть дубли (условие с использованием вложенного запроса). А далее, для того, чтобы сохранить все множество значений номеров строк, нам необходимо по ключевым полям объявить итоги. В таком случае в результате запроса, при использовании механизма итогов, появляются дополнительные строки, в которых хранится итог для того, или иного поля, а сам результат принимает иерархический вид, или вид дерева. Для того, чтобы вывести пользователю сообщение, нам нужно обойти результат запроса, и по каждому набору ключевых полей скомпоновать текст сообщения, и выдать его пользователю.

А теперь попробуем оценить перспективу доработки. Допустим, у нас изменился состав ключевых полей в сторону увеличения их количества: добавились ЕдиницаИзмерения и ЗаказПокупателя. Чтобы контроль дублей строк не перестал работать, нам нужно доработать запрос и обход результата запроса следующим образом:

Запрос = Новый Запрос;
Запрос.УстановитьПараметр(«Ссылка», Ссылка);
Запрос.Текст =
«ВЫБРАТЬ
| ТабЧасть.ЕдиницаИзмерения,
| ТабЧасть.ЗаказПокупателя,
| ТабЧасть.Качество,
| ТабЧасть.Номенклатура,
| ТабЧасть.СерияНоменклатуры,
| ТабЧасть.Склад,
| ТабЧасть.ХарактеристикаНоменклатуры,
| ТабЧасть.НомерСтроки КАК НомерСтроки
|ПОМЕСТИТЬ ВТ_ТабЧасть
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК ТабЧасть
|ГДЕ
| ТабЧасть.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТабЧасть.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
| ТабЧасть.ЗаказПокупателя КАК ЗаказПокупателя,

| ТабЧасть.Качество КАК Качество,
| ТабЧасть.Номенклатура КАК Номенклатура,
| ТабЧасть.СерияНоменклатуры КАК СерияНоменклатуры,
| ТабЧасть.Склад КАК Склад,
| ТабЧасть.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ТабЧасть.НомерСтроки КАК НомерСтроки
|ИЗ
| ВТ_ТабЧасть КАК ТабЧасть
|ГДЕ
| (ТабЧасть.ЕдиницаИзмерения, ТабЧасть.ЗаказПокупателя, ТабЧасть.Качество, ТабЧасть.Номенклатура, ТабЧасть.СерияНоменклатуры, ТабЧасть.Склад, ТабЧасть.ХарактеристикаНоменклатуры) В
| (ВЫБРАТЬ
| ВТ.ЕдиницаИзмерения,
| ВТ.ЗаказПокупателя,
| ВТ.Качество,
| ВТ.Номенклатура,
| ВТ.СерияНоменклатуры,
| ВТ.Склад,
| ВТ.ХарактеристикаНоменклатуры
| ИЗ
| ВТ_ТабЧасть КАК ВТ
| СГРУППИРОВАТЬ ПО
| ВТ.ЕдиницаИзмерения,
| ВТ.ЗаказПокупателя,
| ВТ.Качество,
| ВТ.Номенклатура,
| ВТ.СерияНоменклатуры,
| ВТ.Склад,
| ВТ.ХарактеристикаНоменклатуры
| ИМЕЮЩИЕ
| КОЛИЧЕСТВО(ВТ.НомерСтроки) > 1)
|
|УПОРЯДОЧИТЬ ПО
| НомерСтроки
|ИТОГИ ПО
| Качество,
| Номенклатура,
| СерияНоменклатуры,
| Склад,
| ХарактеристикаНоменклатуры,
| ЕдиницаИзмерения»;
РезЗапроса = Запрос.Выполнить();
Если Не РезЗапроса.Пустой() Тогда
Выб_Качество = РезЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_Качество.Следующий() Цикл
Выб_Номенклатура = Выб_Качество.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_Номенклатура.Следующий() Цикл
Выб_СерияНоменклатуры = Выб_Номенклатура.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_СерияНоменклатуры.Следующий() Цикл
Выб_Склад = Выб_СерияНоменклатуры.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_Склад.Следующий() Цикл
Выб_ХарактеристикаНоменклатуры = Выб_Склад.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_ХарактеристикаНоменклатуры.Следующий() Цикл
Выб_ЕдиницаИзмерения=Выб_ХарактеристикаНоменклатуры.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_ЕдиницаИзмерения.Следующий() Цикл
ТекстСообщения = «»;
Выборка = Выб_ЕдиницаИзмерения.Выбрать();
Пока Выборка.Следующий() Цикл
ТекстСообщения = ТекстСообщения + ?(ПустаяСтрока(ТекстСообщения), «», «, «) + Выборка.НомерСтроки;
КонецЦикла;
ТекстСообщения = «Обнаружено дублирование строк: » + ТекстСообщения;
Сообщить(ТекстСообщения);
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецЦикла;

КонецЕсли;

3) Альтернативный вариант.

Реализация предыдущего варианта другим способом. Предлагаю использовать особенность запросов 1С, позволяющих обращаться к данным табличных частей, как к обычным полям выборки. Ну все-таки не совсем обычным, но все же полям выборки. Кроме того, нам придётся использовать не самый оптимальный способ соединения данных — декартово произведение. Почему так — опишу ниже.

ШаблонОшибки = «Табличная часть ‘Товары’: по реквизитам ‘Качество, Номенклатура, СерияНоменклатуры, Склад, ХарактеристикаНоменклатуры’ обнаружено дублирование строк ‘%1′»;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр(«Ссылка», Объект.Ссылка);
Запрос.Текст =
«ВЫБРАТЬ
| ТабЧасть.Ссылка,
| МИНИМУМ(ТабЧасть.НомерСтроки) КАК МинНомерСтроки,
| ТабЧасть.Качество,
| ТабЧасть.Номенклатура,

| ТабЧасть.СерияНоменклатуры,
| ТабЧасть.Склад,
| ТабЧасть.ХарактеристикаНоменклатуры
|ПОМЕСТИТЬ ВТ_ТабЧасть
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК ТабЧасть
|ГДЕ
| ТабЧасть.Ссылка = &Ссылка
|
|СГРУППИРОВАТЬ ПО
| ТабЧасть.Ссылка,
| ТабЧасть.Качество,
| ТабЧасть.Номенклатура,
| ТабЧасть.СерияНоменклатуры,
| ТабЧасть.Склад,
| ТабЧасть.ХарактеристикаНоменклатуры
| |ИМЕЮЩИЕ
| КОЛИЧЕСТВО(ТабЧасть.НомерСтроки) > 1
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТабЧасть.Ссылка,
| ТабЧасть.Качество,
| ТабЧасть.Номенклатура,
| ТабЧасть.СерияНоменклатуры,
| ТабЧасть.Склад,
| ТабЧасть.ХарактеристикаНоменклатуры,
| Док.Товары.(
| НомерСтроки,
| Качество,
| Номенклатура,
| СерияНоменклатуры,
| Склад,
| ХарактеристикаНоменклатуры
| ) КАК ДублиСтрок
|ИЗ
| (ВЫБРАТЬ
| Док.Товары.(
| НомерСтроки,
| Качество,
| Номенклатура,
| СерияНоменклатуры,
| Склад,
| ХарактеристикаНоменклатуры
| ) КАК Товары
| ИЗ
| Документ.РеализацияТоваровУслуг КАК Док
| ГДЕ
| Док.Ссылка = &Ссылка
| И (Док.Товары.Качество, Док.Товары.Номенклатура, Док.Товары.СерияНоменклатуры, Док.Товары.Склад, Док.Товары.ХарактеристикаНоменклатуры) В
| (ВЫБРАТЬ
| ВТ.Качество,
| ВТ.Номенклатура,
| ВТ.СерияНоменклатуры,
| ВТ.Склад,
| ВТ.ХарактеристикаНоменклатуры
| ИЗ
| ВТ_ТабЧасть КАК ВТ)) КАК Док
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ТабЧасть КАК ТабЧасть
| ПО (ИСТИНА)
|ГДЕ
| Док.Товары.Качество = ТабЧасть.Качество
| И Док.Товары.Номенклатура = ТабЧасть.Номенклатура
| И Док.Товары.СерияНоменклатуры = ТабЧасть.СерияНоменклатуры
| И Док.Товары.Склад = ТабЧасть.Склад
| И Док.Товары.ХарактеристикаНоменклатуры = ТабЧасть.ХарактеристикаНоменклатуры
|
|УПОРЯДОЧИТЬ ПО
| ТабЧасть.МинНомерСтроки,
| Док.Товары.НомерСтроки»;
ТЗ_Результат = Запрос.Выполнить().Выгрузить();
Для Каждого СтрТЗ Из ТЗ_Результат Цикл
Сообщить(СтрШаблон(ШаблонОшибки, СтрСоединить(СтрТЗ.ДублиСтрок.ВыгрузитьКолонку(«НомерСтроки»), «, «)));
КонецЦикла;
Главное отличие от предыдущего варианта: обход результата запроса осуществляется линейным способом. Т.е. при изменении состава ключевых полей меняется только текст запроса.

Несколько комментариев по поводу запроса.

Работа с табличными частями в качестве полей выборки накладывает ряд ограничений на выполнение запросов. Во-первых, это работа с временными таблицами. Т.е. нельзя помещать такие объекты во временные таблицы, но никто не мешает использовать вложенные запросы. Во-вторых, это соединения таблиц. Мне требовалось написать такой запрос, который бы возвратил мне наборы ключевых полей по которым имеются дубли, и многострочный объект, содержащий все строки с таким же набором ключевых полей. Обычные соединения (ВНУТРЕННЕЕ, ЛЕВОЕ, ПРАВОЕ, ПОЛНОЕ) возвращают всю табличную часть, что, в общем, правильно – для части объекта условие соединения же выполняется? Выполняется. Ну тогда и получите всю табличную часть. Искомый результат, как оказалось, достигается декартовым произведением. Мне как-то претит видеть в тексте запроса перечисление таблиц через запятую, поэтому я все декартовы произведения всегда реализую через «… СОЕДИНЕНИЕ … ПО (ИСТИНА)». Чтобы ограничить мсье Декарта в аппетитах (и повысить производительность), применяются дополнительные ограничения.

Теперь о производительности. Производились тестовые замеры каждого из вариантов на документе с большим количеством строк в табличной части. Количество строк в тестируемом документе: 47 817, 4 комбинации ключевых полей с дублями по 2, 2, 3 и 4 строки. Результаты замеров:

Вариант 1) 0:00:00.078 сек.

Вариант 2) 0:00:00.265 сек.

Вариант 3) 0:00:01.513 сек.

Как видим, третий вариант, как и ожидалось, самый медленный, но он же является самым удобным в перспективе модификации.

Прилагаемая обработка является демонстратором третьего варианта. Работает она и в обычном, и в управляемом режимах. Внешний вид и функционал полностью одинаков.

1) Выбираем вид объекта: Документ или Справочник.

2) Выбираем тип объекта: Какой именно документ или справочник.

3) Выбираем табличную часть объекта.

4) Определяем состав ключевых полей в специальном диалоге

5) Если мы хотим, то можем указать ссылку на объект, чтобы проверить его на наличие дублей.

6) Если активен флажок «Сгенерировать и показать код для проверки на дубли», то будет сгенерирован программный код для выполнения проверки на дубли строк с имеющимися настройками.

Где меняются счета учёта номенклатуры оглавление Хитрости при работе в 1С Часть 4

Хитрости при работе в 1С:Бухгалтерии 8.3 (редакция 3.0) Часть 3

2016-12-08T13:53:16+00:00

Этой статьей я продолжаю серию заметок об эффективных приемах работы в 1С:Бухгалтерия 8.3. Рассказываю о хитростях, которые мало кто знает и ещё меньше людей используют в своей работе. Приемы, о которых пойдет речь, способны существенно сэкономить время и повысить вашу квалификацию как специалиста. Предыдущие части доступны (ч.1) и (ч.2).

Прием №10: групповые операции над справочниками и документами

Помните во второй части я рассказывал как легко и просто вывести на печать сразу несколько документов из журнала?

С тех пор 1С значительно расширило возможности групповых операций и сегодня мы с ними познакомимся. Возможности действительно классные и, я уверен, каждый бухгалтер найдёт их крайне полезными в своей ежедневной работе.

Итак, поехали!

Прежде всего, что такое групповая операция? Это, когда мы проводим какую-либо операцию (например, печатаем, проводим, изменяем) сразу над группой объектов. Вместо того, чтобы выполнять эту операцию по очереди над каждым элементом группы.

Над чем можно проводить групповые операции? Над элементами справочников и документами.

Групповые операции проводятся над выделенными объектами.

Вспомним, как легко и просто выделить сразу несколько документов в журнале (с элементами справочников всё точно также):

  • Чтобы выделить сразу несколько документов зажимаем клавишу CTRL на клавиатуре и мышкой «тыкаем» в нужные документы.
  • Чтобы выделить все видимые документы в журнале нажимаем комбинацию клавиш CTRL + A.
  • Чтобы выделить несколько последовательно идущих документов используем на клавиатуре кнопки со стрелками ВВЕРХ или ВНИЗ, удерживая клавишу SHIFT.

А теперь примеры

Распроводим группу выделенных документов

Проводим группу выделенных документов

Помечаем на удаление группу выделенных документов (или наоборот снимаем)

Отправляем по почте выделенные документы (одну из их печатных форм)

Выводим на печать выделенные документы

Изменяем реквизиты выделенных документов

К примеру, сменим склад во всех выделенных документах.

Для этого выделяем нужные документы, нажимаем на них правой кнопкой и выбираем пункт «Изменить выделенные…»:

В открывшейся форме на закладке «Реквизиты» устанавливаем основной склад и нажимаем кнопку «Изменить реквизиты»:

Ожидаем некоторое время:

Готово:

Изменяем табличную часть выделенных документов

К примеру, сменим во всех строках табличной части «Товары» ставку НДС на «Без НДС».

Для этого выделяем нужные документы, нажимаем на них правой кнопкой и выбираем пункт «Изменить выделенные…»:

В открывшейся форме переходим на закладку «Товары», устанавливаем нужную ставку НДС и нажимаем кнопку «Изменить реквизиты»:

Мы молодцы, на этом всё

А я напоследок хочу напомнить, что точно таким же образом групповые операции можно проводить над элементами справочников.

Продолжение .

Кстати, подписывайтесь на новые уроки…

С уважением, Владимир Милькин (преподаватель школы 1С программистов и разработчик обновлятора).

Подписывайтесь и получайте новые статьи и обработки на почту (не чаще 1 раза в неделю).
Вступайте в мою группу ВКонтакте, Одноклассниках, Facebook или Google+ — самые последние обработки, исправления ошибок в 1С, всё выкладываю там в первую очередь.

Как помочь сайту: расскажите (кнопки поделиться ниже) о нём своим друзьям и коллегам. Сделайте это один раз и вы внесете существенный вклад в развитие сайта. На сайте нет рекламы, но чем больше людей им пользуются, тем больше сил у меня для его поддержки.

Нажмите одну из кнопок, чтобы поделиться:

Где меняются счета учёта номенклатуры оглавление Хитрости при работе в 1С Часть 4

Технология ActiveDocument предназначена для редактирования документов внешними по отношению к 1С:Предприятию 8 редакторами.

Эта технология позволяет редактировать документы визуально (например, Word или Excel) непосредственно в окне 1С:Предприятия 8, при этом элементы пользовательского интерфейса (меню, панели команд и т. д.) заменяются на предоставляемые редактором. Документы могут быть предварительно отредактированы и сохранены в макетах конфигурации, а затем макеты могут использоваться пользователями как основы для создания окончательных версий документов.

Следует заметить, что использование макетов ActiveDocument в режиме Предприятия осуществляется только программно — визуальное редактирование возможно только на этапе создания и редактирования конфигурации.

Эта технология применяется в случае, когда в конфигурации необходимо хранить данные, редактируемые другим приложением — такие, например, как шаблоны для факсов или деловых писем, созданные в Microsoft Word, или шаблоны прайс-листов в Microsoft Excel. Такая необходимость возникает, как правило, при регламентировании формата документов (как во внутреннем документообороте, так и при обмене документами со сторонними организациями и клиентами), однако при отсутствии ограничений на формат документа рекомендуется использовать существующие в 1С:Предприятии 8 возможности по оформлению электронных и печатных документов.

1С перейти к строке по номеру

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *