Как исключить счет из запроса 1с
Зачастую нужно заранее сделать выборку из базы данных по некоему условию. Для этого в 1С 8.3 необходимо использовать вложенные запросы.
Но следует учитывать, что в большинстве случаев вложенные запросы в 1С бесполезны без соединения их результата с другими таблицами. Такое соединение практически в любом случае приведет к сильному замедлению выполнения запроса в целом.
Пример вложенного запроса на языке запросов
Приведу пример вложенного запроса на языке запросов 1С. Допустим, нам нужно сделать выборку суммы некоторого остатка по отдельным клиентам на определенную дату:
ВЫБРАТЬ
НераспОплатыОстатки.Заказчик,
НераспОплатыОстатки.СуммаОст
ИЗ(ВЫБРАТЬ
Заказчики.Ссылка КАК СсылкаНаСпрЗаказчики
ИЗ
Справочник.Заказчики КАК Заказчики
ГДЕ
Заказчики.Ссылка В(&Заказчики)) КАК ВложЗапросЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления. НераспОплаты.Остатки КАК НераспОплаты
ПО ВложЗапрос.СсылкаНаСпрЗаказчики = НераспОплатыОстатки.Заказчик
Когда СУБД будет выполнять такой запрос, не исключены неверные действия оптимизатора, так как трудно определиться с планом обработки запроса. Когда СУБД соединяет две таблицы, оптимизатор строит алгоритм на основе вычисления количества записей в этих таблицах.
Когда же используется вложенный запрос, вычислить количество записей, вернувшихся из вложенного запроса, очень трудно.
Как лучше?
Именно поэтому фирма 1С крайне не рекомендует использовать вложенные запросы, а вместо них разработала временные таблицы. С использованием временных таблиц наш предыдущий запрос будет выглядеть так:
// Временная таблица
ВЫБРАТЬ
Заказчики.Ссылка КАК Заказчики
ПОМЕСТИТЬ табЗаказчики
ИЗ
Справочник.Заказчики КАК Заказчики
ГДЕ Заказчики.Ссылка В (&Заказчики)
;// Основной запрос
ВЫБРАТЬ
табКлиенты.Ссылка,
НераспОплатыОстатки.СуммаОст,
ИЗ
табЗаказчики КАК табЗаказчики
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.НераспОплаты.Остатки(
,
Заказчик В
(ВЫБРАТЬ
табЗаказчики.Заказчики
ИЗ
табЗаказчики)) КАК НераспОплатыОстатки
ПО табЗаказчики.Заказчики = НераспОплатыОстатки.Заказчики
Смотрите также видео-урок про вложенные запросы:
Если вы только начинаете программировать в 1С или просто хотите систематизировать свои знания - попробуйте Школу программирования 1С нашего друга Владимира Милькина. Пошаговые и понятные уроки даже для новичка с поддержкой учителя.
Попробуйте бесплатно по ссылке >>
Теперь оптимизатор знает заранее, сколько записей во временной таблице, и без труда оптимизирует алгоритм выполнения соединения таблиц.
Если Вы начинаете изучать 1С программирование, рекомендуем наш бесплатный курс (не забудьте подписаться на YouTube — регулярно выходят новые видео):
Есть запрос. Его результатом является определенное кол-во строк. Но маленький набор строк из него нужно исключить. Этот маленький набор строк можно получить другим запросом.
Как правильнее реализовать єто задачу? Сделать вложенный запрос? Можно ли в этом случае объединить основную и вложенную таблицы так, чтоб из основного набора данных исключались данные второго запроса?
Или лучше сделать Запрос пакета 2, и проверять чтоб данные первого набора данных были НЕ В втором наборе?
+(3) Вроде ж по левому должны войти все строки большого запроса, и те из маленького, которые соответствуют условию соединения. Может внутреннее?
(8) использовать "В" имеет смысл только в условии джойна.
в (1) самый оптимальный путь, по сколько джойн большого с малым очень быстрый и проверка на нулл в конце то-же быстрая
(9) Так условие все-таки в джойне или в в ГДЕ, в верхнем запросе? Я так понял что получается бесполезный джойн (новых колонок не добавляется) а потом уже в ГДЕ условие на невхождение во вложенный запрос.
(10) проверка на нулл конечно в секции "где", то есть сначало джойн а потом условие на нулл по маленькой таблице, тем самым мы оставим только записи из большой таблице которых нет в маленькой
(13)
в(12) прделагает сразу проверку наложить на невхождение в список из подзапроса.
Вопрос только в том, что быстрее будет соедеинение и простой отбор НЕ Есть Null
или отбор с условием Не В (список из подзапроса)
(14),(15) Вопрос имеет смысл если этот джойн сам лишние строки уберет, то есть будет не левый, а внутренний и за счет условий соединения в итоговой таблице останется только то что надо, в данном же случае он этого не делает, и используется только для того чтобы в основном запросе можно было обратиться к полю вложенного. Что в общем-то и не нужно.
(9) Почему?
Чем такой запрос плох?
(16) (17) Неудобство в сопоставлении реквизитов, что если связать нужно будет не по ссылке, а одновременно еще и по дате.
К тому же фирма 1С рекомендует так не делать, т.к. возможно появление тормозов.
В общем на выбор.
(18) Ну так джойн надо внутренний использовать, а не левый. В условиях соединения все и проверять, чтобы именно он убрал лишнее. А с левым те же яйца только в профиль, все равно в where проверка, а не в on.
(20) Вот запрос от балды, хочется увидеть вариант с внутренним соединением (для самообразования так сказать).
Получить не праздничные дни из графика
[1с]
ВЫБРАТЬ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря
ПОМЕСТИТЬ ВТПразднечныеДни
ИЗ
РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ГДЕ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря >= &ДатаНачала
И РегламентированныйПроизводственныйКалендарь.ДатаКалендаря И РегламентированныйПроизводственныйКалендарь.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Праздник)
ИНДЕКСИРОВАТЬ ПО
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ГрафикиРаботыПоВидамВремени.ГрафикРаботы,
ГрафикиРаботыПоВидамВремени.Дата,
ГрафикиРаботыПоВидамВремени.ОсновноеЗначение
ИЗ
РегистрСведений.ГрафикиРаботыПоВидамВремени КАК ГрафикиРаботыПоВидамВремени
ЛЕВОЕ СОЕДИНЕНИЕ ВТПразднечныеДни КАК ВТПразднечныеДни
ПО ГрафикиРаботыПоВидамВремени.Дата = ВТПразднечныеДни.ДатаКалендаря
ГДЕ
ГрафикиРаботыПоВидамВремени.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
И ГрафикиРаботыПоВидамВремени.ГрафикРаботы = &ГрафикРаботы
И ГрафикиРаботыПоВидамВремени.План
И ВТПразднечныеДни.ДатаКалендаря ЕСТЬ NULL
[/1с]
Нужно в него добавить дополнительное условие:
Исключить из оборотов счета с определенной аналитикой.
Список этих счетов с аналитикой заполняется скажем в РС "ИсключаемаяАналитика"
с реквизитами:
-Счет
-СубКонто1
-СубКонто2
-СубКонто3
где обязательны к заполнению Счет и хотя бы одно из СубКонто
Вопрос:
Как всунуть в вышеприведенный текст запроса условие исключения этих записей из РС?
создаёте временную таблицу ИсключаемыеСчета
а потом в параметрах виртуальной таблицы Обороты добавляете фильтрацию Счета по ВТ ИсключаемыеСчета
romansun пишет:
в параметрах виртуальной таблицы Обороты добавляете фильтрацию Счета по ВТ ИсключаемыеСчета
Но ведь нужна фильтрация не просто по счетам а по счетам с определенной аналитикой
(3) хм, мне надо обдумать Ваш совет
(4)
ну так вы напишите такой запрос, который отберет вам в исключаемую таблицу только счета с определенной аналитикой, и вообще с каким-либо угодным условием
а если возможно обойтись условием по субконто, то, да - (3)
romansun пишет:
запрос, который отберет вам в исключаемую таблицу только счета с определенной аналитикой,
По условию нужно отбирать все аналитики кроме некоторых исключаемых.
В параметры, я так понимаю, (я пока плохо с этим разбираюсь) это условие не засунешь, ибо параметр Счет не поймет ограничения по СубКонто, а параметр СубКонто не поймет ограничения по Счету.
Похоже мне нужно смотреть в комментарий (3).
Итак, мне нужно:
- получить список исключаемых субконто
- разбить их на три списка по номерам субконто 1, 2, 3
- и добавить в параметр Условие:
нет, что-то слишком коряво вышло
P.S.
Я только что уточнил задание (на обеде все были не у кого было уточнить ранее), что счет в исключаемых аналитиках тот же что и в условии Счет.
Так что tango в (3) быстро просек всю ситуацию даже с неполными входящими и дал лаконичный, но точный ответ :)
Спасибо.
Но все же мне не нравится мое корявое решение с разбиением ограничений на три списка.
Как бы все это совместить в одном.
что в условие по счету, что по субконто можно писать запросы вида
Счет не в (Выбрать Счет из . где . )
Субконто1 не в (Выбрать Субконто из . где . )
т.е. полноценные выборки, которые на выходе дадут счет (список счетов) или субконто (список субконт). Этим можно оперировать при констурировании параметров у виртуальных таблиц.
PS
вот, кстати и пиар типа - возможно станет яснее с параметрами :)
romansun пишет:
что в условие по счету, что по субконто можно писать запросы вида
Счет не в (Выбрать Счет из . где . ) Субконто1 не в (Выбрать Субконто из . где . )
т.е. полноценные выборки, которые на выходе дадут счет (список счетов) или субконто (список субконт).
мне сдается, что в этом случае получится что условия не пересекаются, ведь тут ИЛИ,
и не попадет ли на другой счет субконто?
Тут нужно И (счет И субконто вместе в связке)
Здается мне что тут нужно смотреть 6 параметр УСЛОВИЕ, там где "Организация = &Организация".
Читаю цитату из "Проф. разработки" Габеца и ко.
"параметр Условие - содержит конструкцию языка запросов. Позволяет установить отбор данных виртуальной таблицы по значениям субконто и измерений регистра бухгалтерии".
Хотя, впрочем нет, ведь здесь тоже не написано про счет, ведь счет это не измерение.
Ну счас проверю.
Да в параметр Условие счет не всунешь :(
И все же задание изменилось!
После обдумывания бухи решили, что счет в условии исключения может быть и родителем и любым из его дочерних.
В случае если есть ограничения и на родителя и на детей то нужно добавлять ограничения родителя к ограничениям детей.
Ужас какой-то.
Я в шоке!
Сижу и пытаюсь сообразить как сформировать запрос по этим условиям.
слушайте, может я туплю, но всё-таки не понимаю, если вариант с субконто напрямую не проходит, то что мешает написать обычный полноценный запрос, который отберет все ненужные счета, с учетом аналитики, родителей, детей, бухов, и фаз Луны
запихать их во временную таблицу
а потом в параметре виртуальной таблицы написать условие "Счет НЕ В (Выбрать Счет из ВТ_НенужныеСчета)"?
или проблема уже именно в отборе ненужных счетов?
romansun пишет:
а потом в параметре виртуальной таблицы написать условие "Счет НЕ В (Выбрать Счет из ВТ_НенужныеСчета)"?
А как же условия на субконто?
Ведь не счет нужно выбрасывать, а только некоторые проводки по счету с определенными значениями субконто?
Это для распределения затратных счетов.
Нужно исключить из распределения некоторые
- Подразделения(Субконто1)
- Номенклатурные группы(Субконто2)
- Статьи затрат(Субконто3)
А условие по корСчетам уже есть, правда пока без аналитики :D
Думаю наверное надо делать так
дописывать в условие запроса ГДЕ конструкцию типа:
В (13) ошибся, нужно вместо ИНАЧЕ второй ВЫБОР чтобы сложить ограничения счета-родителя и его субсчета
ГДЕ
ВЫБОР
КОГДА счет В ИЕРАРХИИ (&Счет) // счет-группа
ТОГДА Ложь
ИНАЧЕ Истина
КОНЕЦ // 1
// +++
ВЫБОР
КОГДА счет = (&Счет) // субсчет
И
ТОГДА Ложь
.
ИНАЧЕ Истина
КОНЕЦ // 2
КОНЕЦ КАК ИсключаемаяПроВодка
(11) Да, хорошо было бы засунуть ненужные данные во временную таблицу,
но как потом взять разность двух таблиц: нужной и ненужной?
подкинь бухам сабж: надо ли исключать корр счета с запретной аналитикой.
Кстати, зачем им это, практически?
(12) ограничивать по ГДЕ не комильфо :)
Т.е., это все-таки не задача консолидации (элиминации), а скрытие "серого"? Фигня какая-то. Что-то говорит мне, что нефига тогда было класть это на затраты.
ну, если бы серьёзная задача стояла бы именно так. я бы замутил хранимую процедуру типа
SELECT city
FROM authors
EXCEPT
SELECT city
FROM publishers;
(20) Спасибо, tango, за совет.
Но у меня нет прав к самому SQL-серверу, я не админ, а обычный программер.
Меня привлекает следующий вариант:
Поскольку оператор "В" допускает конструкцию с
Ну и как-то отсеять незаполненные субконто,
надо подумать как, через ВЫБОР . (типа:
КОГДА СубКонто1 <> ЗНАЧЕНИЕ(Справочник.ПодразделенияОрганизаций.ПустаяСсылка)
ТОГДА
Таблица1.СубКонто1 = Таблица2.СубКонто1
)
ибо как-то не хочется, динамически формировать запрос в зависимости от условий, т.к. Конструктору такие условия скормить проблемно.
Ой, ну каша в голове, ибо занялся другой проблемой, оставив эту пока созревать :)
Набросал счас махонькую обработку, для проверки синтаксиса оператора "В"
вот ее код:
Вот результат.
Не совсем пока то что нужно,
ибо не обрабатываются незаполненные значения из тз1,
а мне нужно еще выбросить и те строки из тз2 где хотя бы одна колонка из трех в тз2 совпадает с сответствующей колонкой из тз1.
Т.е, судя по рисунку, строки 1 и 2 из тз2 не должны попасть в тз4.
В тз4 должна быть только строка 4.
Как сделать, может кто подкинет красивое решение.
Простите, но я наверное уже всем надоел?
Переделал немного обработку чтобы ближе к реальным данным условия задачи
Вот что получилось, извините за длинный код.
Как упростить условие НЕВхождения в Процедуре ВыполнитьНЕВНажатие(),
ибо 7 вариантов - это немного слишком мне кажется?
Прилагаю саму обработку в архиве, на всякий случай, если кто захочет поковыряться, а текст набирать лень.
Тестируется на конфигурации "Бухгалтерия Предприятия".
Оба на!
Я упустил из виду что еще если Счет В ИЕРАРХИИ, а не только равен, то надо исключить проводку из попадания в тз4 :(
Условие усложняется, увы!
(26) Спасибо за внимание, конечно, но, увы, я еще исключение принадлежности счета по иерархии не обработал.
А в понедельник уже нужно сдать работу, - вот сижу и ломаю голову.
скажите, а внешнее соединение в запросе разве не подходит?
я набросал себе пример тут, результат такой:
и текст запроса:
то система выкидывает ошибку что поле не найдено?
Я же ведь просто от существующего в тз1 поля "Счет" беру его родителя.
Это только какая-то особенность в работе со временными таблицами?
Здравствуйте! Есть немаленький Запрос и в нем формируются Итоги следующим образом: Возможно ли исключить из общих итогов, например суммы из группировки ОсновнойОбороты.КорСчет?
Да. Помещением еще в 1 временную таблицу без этого поля, гркппировкой и потом объединением с этой же таблицей, но только с выбранным 1 полем.
почём мне знать, как тебе надо. Я в рабочий вариант показал, который работает. Дальше - сам. Или говори, что конкретно сделал, что получилось в результате и что должно было получиться. Конкретно.
ВЫБОР КОГДА ОсновнойОбороты.КорСчет ЕСТЬ NULL ТОГДА СУММА(Основной.СуммаНачальныйОстаток) КОНЕЦ КАК СуммаНачальныйОстаток, Вот так написал, но в общих итогах все равно входит сумма по группировке ОсновнойОбороты.КорСчет.
ну, а теперь перечитай то, что я написал. Особо пристальное внимание обоими глазами одновременно обрати на мета, в которых я скобки расставил, и в которых - ты, а еще на положение слова СУММА относительно ВБОРКОГДАТОГДА
СУММА (ВЫБОР КОГДА ОсновнойОбороты.КорСчет ЕСТЬ NULL ТОГДА Основной.СуммаНачальныйОстаток КОНЕЦ ) С такой конструкцией итоги СуммаНачальныйОстаток ПО ОБЩИЕ равны 0. : 8
И все таки что-то не так. Гляньте пожалуйста: Вот сумма 95987,07 и должна быть в ОБЩИХ итогах. Что-то не получается ее вывести.
Хорошо, может быть вопрос не был поставлен корректно с самого начала. Вот текст Запроса: Основной.Фирма, Основной.Субконто1, ОсновнойОбороты.Регистратор, Основной.СуммаНачальныйОстаток КАК СуммаНачальныйОстаток, ОсновнойОбороты.СуммаОборотДт КАК Приход, ОсновнойОбороты.СуммаОборотКт КАК Расход, Основной.СуммаКонечныйОстаток КАК СуммаКонечныйОстаток ИЗ РегистрБухгалтерии.Основной.ОстаткиИОбороты( &ДатаКон, , ВЫБОР КОГДА &БезФирм = 0 ТОГДА ИСТИНА ИНАЧЕ Фирма В (&Фирма) КОНЕЦ И ВЫБОР КОГДА &БезФил = 0 ТОГДА ИСТИНА ИНАЧЕ Филиал В (&Филиал) ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Основной.Обороты( &ДатаНач, , ВЫБОР КОГДА &БезФирм = 0 ТОГДА ИСТИНА ИНАЧЕ Фирма В (&Фирма) КОНЕЦ И ВЫБОР КОГДА &БезФил = 0 ТОГДА ИСТИНА ИНАЧЕ Филиал В (&Филиал) КОНЕЦ И ВЫБОР КОГДА &КорСуб1 = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка) ТОГДА ИСТИНА КорСчет В (&СписокКорСчетов)) КАК ОсновнойОбороты ПО Основной.Фирма=ОсновнойОбороты.Фирма И Основной.Субконто1=ОсновнойОбороты.Субконто1 УПОРЯДОЧИТЬ ПО Основной.Фирма,Основной.Субконто1, ОсновнойОбороты.Регистратор АВТОУПОРЯДОЧИВАНИЕ ИТОГИ ПО ОБЩИЕ, Основной.Фирма, Основной.Субконто1, ОсновнойОбороты.Регистратор Если запрос в таком виде то все получается так как надо, итоги выходят нормально. Но если добавить ОсновнойОбороты.КорСчет в итогах ПО и в выборке - то итоги по ОБЩИЕ выходят криво Вот первый вариант где все ОК: А вот второй, с добавлением ОсновнойОбороты.КорСчет Объясните пожалуйста, почему такое происходит?
Автоматизация обмена данных используя обработку "Универсальный обмен данными в формате XML" 10
Автоматизация обмена между базами используя обработку " Универсальный обмен данными в формате XML" В основу данной публикации положены найденные мною материалы по cозданию обмена между двумя базами с использованием обработки " Универсальный обме Автоматическая выгрузка загрузка данных используя регламентное задание 12
Для обмена данными между программами необходимо сделать следующее: 1. При помощи Конвертации Данных создать правила выгрузки данных 2. Нужно чтобы в конфигурации была обработка УниверсальныйОбменДаннымиXML , желательно последней версии! (При помо База 1С вылетает, виснет, не грузится, падает с ошибкой? 0
Есть ряд методов, которыми можно попытаться " поднять" упавшую базу 1С 8.х Но сперва нужно сделать резервную копию! Сделайте резервную копию простым копированием папки базы, выгрузка не всегда может быть корректна. Удалить все файлы в папке базы, Взаимодействие с Контрольно-Кассовыми Машинами (ККМ) 1
Имеется ли возможность взаимодействия конфигурации Управление торговлей с контрольно-кассовыми машинами (ККМ)? Данная возможность реализована в конфигурации в трех вариантах: ККМ в режиме фискального регистратора, ККМ в режиме Offline, ККМ в Внешние источники данных 0
Почему данная возможность вызывает такой интерес? Любой человек, который программировал в 1С при этом достаточно неплохо знаком с SQL и хотя бы в общих чертах знаком с архитектурой и принципами разработки других технологических платформ для бизнес пр Посмотреть все результаты поиска похожих
Еще в этой же категории
Значения NULL ( ЕСТЬ NULL и ЕСТЬNULL()) 48
NULL – отсутствующие значения. Не путать с нулевым значением! NULL – это не число, не равно пробелу, пустой ссылке, Неопределено. NULL – типообразующее значение, т.е. есть тип NULL и единственное значение этого типа. NULL значения появляются в 17 правил для составления оптимального ЗАПРОСа к данным базы 1С 44
Для формирования и выполнения запросов к таблицам базы данных в платформе 1С используется специальный объект языка программирования Запрос . Создается этот объект вызовом конструкции Новый Запрос . Запрос удобно использовать, когда требуется получ Нарастающий итог в запросе 23
Необходимо использовать левое соединение таблицы с самой собой. ВЫБРАТЬ Обороты.Период, Обороты.Номенклатура, Обороты.Количество ПОМЕСТИТЬ ВТдвижения ИЗ РегистрНакопления.Обороты КАК Обороты ; //////////////////////////////////////////////// Полезные сведения о языке запросов 1С 8.х 22
В статье приведены полезные приемы при работе с запросами 1С v.8.2, а также сведения, которые не так хорошо известны о языке запросов. Я не стремлюсь дать полное описание языка запросов, а хочу остановиться лишь на некоторых моментах, которые для ко Оператор ПОДОБНО 19
ПОДОБНО - Оператор проверки строки на подобие шаблону. Аналог LIKE в SQL. Оператор ПОДОБНО позволяет сравнить значение выражения, указанного слева от него, со строкой шаблона, указанной справа. Значение выражения должно иметь тип строка. Если з Посмотреть все в категории Запросы
Читайте также: