Разница между датами в рабочих днях, подсчет рабочих дней в 1С Разрабатывая некий функционал в 1С, бывает, необходимо посчитать количество рабочих дней после какой-то даты.
В этой статье примеры кода и запросы в которых считается количество рабочих дней:
Код, при вычислении определяет только по дню недели, викидывая выходные. Праздники не учитывает!
Код 1C v 8.х Функция РабочихДнейСДаты(НачДата,КолвоДней) Экспорт
Перем РабочихДней, ОбычныхДней, ДеньНедели;
РабочихДней = 0; ОбычныхДней = 0;
Пока РабочихДней < Число(КолвоДней) Цикл
ОбычныхДней = ОбычныхДней+ 1;
// определим день недели
ДеньНедели=ДеньНедели(НачДата+(ОбычныхДней*86400));
// если не выходной, то прошел еще один рабочий день
Если ДеньНедели < 6 Тогда
РабочихДней=РабочихДней+1;
КонецЕсли;
КонецЦикла;
Возврат (НачДата + (РабочихДней*86400));
КонецФункции
// Пример использования
ТриДняОтОбработки = РабочихДнейСДаты(нДатаОбработки,3);
Если РабочаяДата>ТриДняОтОбработки Тогда
Предупреждение("Прошло больше 3-х дней после обработки заказа. Цены не актуальны!
|Отправьте заказ на новую обработку! ");
Иначе
// ... неки код
КонецЕсли;
В запросе, с использованием производственного календаря и учетом всех праздников:
Код 1C v 8.х ВЫБРАТЬ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря КАК Дата
ПОМЕСТИТЬ Даты
ИЗ
РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ГДЕ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря В(&ВходящиеДаты)
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Даты.Дата,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ РегламентированныйПроизводственныйКалендарь.ДатаКалендаря) КАК КоличествоРабочихДней,
МАКСИМУМ(РегламентированныйПроизводственныйКалендарь.ДатаКалендаря) КАК ДатаКалендаря,
РегламентированныйПроизводственныйКалендарь1.ДатаКалендаря КАК ДатаКалендаряДляГруппировки
ИЗ
РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Даты КАК Даты
ПО (Даты.Дата <= РегламентированныйПроизводственныйКалендарь.ДатаКалендаря)
И (ДОБАВИТЬКДАТЕ(Даты.Дата, ДЕНЬ,ГлубинаДней) > РегламентированныйПроизводственныйКалендарь.ДатаКалендаря)
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь1
ПО РегламентированныйПроизводственныйКалендарь.ДатаКалендаря <= РегламентированныйПроизводственныйКалендарь1.ДатаКалендаря
ГДЕ
(РегламентированныйПроизводственныйКалендарь.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Предпраздничный)
ИЛИ РегламентированныйПроизводственныйКалендарь.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий))
СГРУППИРОВАТЬ ПО
РегламентированныйПроизводственныйКалендарь1.ДатаКалендаря,
Даты.Дата
ИМЕЮЩИЕ
МАКСИМУМ(РегламентированныйПроизводственныйКалендарь.ДатаКалендаря) = РегламентированныйПроизводственныйКалендарь1.ДатаКалендаря
И КОЛИЧЕСТВО(РАЗЛИЧНЫЕ РегламентированныйПроизводственныйКалендарь.ДатаКалендаря) =РабочихДней
Еще один вариант, в котором допустим, что:
1) Регистр сведений Календарь имеет структуру (Измерения={ДатаКалендаря}, Ресурсы={ВидДня}), а перечисление ВидыДня задано как {Рабочий, Предпразничный} и праздничные дни в календаре отсутствуют.
2) В документе Реализация заданы поля Дата и ОтсрочкаДней. Тогда:
Код 1C v 8.х Выбрать
Р.Ссылка, Р.Дата,
минимум(isnull(К.ДатаКалендаря, добавитькдате(Р.Дата, день, Р.ОтсрочкаДней))) как ДатаКредита
из Документ.Реализация как Р
левое соединение РегистрСведений.Календарь как К
по добавитькдате(Р.Дата, день, Р.ОтсрочкаДней) <= К.ДатаКалендаря
сгруппировать по
Р.Ссылка, Р.Дата
Собственно, если календарь содержит и праздничные дни, то можно добавить секцию ГДЕ, и там отобрать только рабочие дни. В секции ГДЕ можно отобрать и интересующий календарь, если ведется несколько календарей.
Категория:
Работа с Датами (Временем) Объектная модель схемы запроса Периодически во встроенном языке возникает необходимость изменения текста запроса в зависимости от разных алгоритмических условий. Раньше подобная задача решалась путём непосредственного формирования нужного текста запроса в виде строки. А это не всегда удобно и зачастую очень громоздко.
Теперь во встроенном языке мы реализовали объектную модель схемы запроса. Вы можете создать пустую схему запроса конструктором и загрузить в неё имеющийся текст запроса. После этого отдельные элементы текста запроса будут доступны вам как свойства объектной модели.
На рисунке ниже стрелки показывают, в каких объектах встроенного языка будут доступны те или иные элементы простого запроса, загруженного в схему:
Редактирование текста запроса с помощью объектной модели позволяет вам проще и понятнее модифицировать имеющиеся запросы. Или даже создавать их во встроенном языке «с нуля». А затем просто получать готовый текст запроса из схемы методом ПолучитьТекстЗапроса() .
Пример использования Схемы запроса Код 1C v 8.3 //Создание схемы запроса
СхемаЗапроса = Новый СхемаЗапроса;
ЗапросВыбораИзИБ = СхемаЗапроса.ПакетЗапросов[0];
//Установка свойств запроса
ЗапросВыбораИзИБ.ТаблицаДляПомещения = "ТаблицаОбороты";
ЗапросВыбораИзИБ.ВыбиратьРазрешенные = Истина;
//Добавляем операторы выбора первого запроса пакета
ОператорВыбораЗакупок = ЗапросВыбораИзИБ.Операторы[0];
ИсточникНоменклатура = ОператорВыбораЗакупок.Источники.Добавить("Справочник.Номенклатура","Товары");
//Добавляем запрос выбора из регистра закупок
ИсточникЗакупки = ОператорВыбораЗакупок.Источники.Добавить("РегистрНакопления.Закупки.Обороты","Закупки");
ИсточникЗакупки.Источник.Параметры[0].Выражение = Новый ВыражениеСхемыЗапроса("&Начало") ;
ИсточникЗакупки.Источник.Параметры[1].Выражение = Новый ВыражениеСхемыЗапроса("&Окончание") ;
ИсточникЗакупки.Источник.Параметры[2].Выражение = Новый ВыражениеСхемыЗапроса("Месяц") ;
//Меняем тип соединения
ИсточникЗакупки.Соединения[0].ТипСоединения = ТипСоединенияСхемыЗапроса.ПравоеВнешнее;
//Указываем выбираемые поля
ОператорВыбораЗакупок.ВыбираемыеПоля.Добавить("Товары.Ссылка");
ОператорВыбораЗакупок.ВыбираемыеПоля.Добавить("Закупки.Период");
ОператорВыбораЗакупок.ВыбираемыеПоля.Добавить("ЕСТЬNULL(Закупки.СуммаОборот, 0)");
ОператорВыбораЗакупок.ВыбираемыеПоля.Добавить("0");
//Указываем спевдонимы для выбранных полей
ЗапросВыбораИзИБ.Колонки[0].Псевдоним = "Номенклатура";
ЗапросВыбораИзИБ.Колонки[1].Псевдоним = "Период";
ЗапросВыбораИзИБ.Колонки[2].Псевдоним = "СуммаЗакупок";
ЗапросВыбораИзИБ.Колонки[3].Псевдоним = "СуммаПродаж";
//Добавляем отбор
ОператорВыбораЗакупок.Отбор.Добавить("НЕ Товары.ЭтоГруппа");
///////////////////////
//Выбираем данные о продажах
ОператорВыбораПродаж = ЗапросВыбораИзИБ.Операторы.Добавить();
ИсточникНоменклатура = ОператорВыбораПродаж.Источники.Добавить("Справочник.Номенклатура","Товары");
ОператорВыбораПродаж.ВыбираемыеПоля.Добавить("Товары.Ссылка");
//Добавляем источник РН и устанавливаем параметры
ИсточникПродажи =ОператорВыбораПродаж.Источники.Добавить("РегистрНакопления.Продажи.Обороты","Продажи");
ИсточникПродажи.Источник.Параметры[0].Выражение = Новый ВыражениеСхемыЗапроса("&Начало") ;
ИсточникПродажи.Источник.Параметры[1].Выражение = Новый ВыражениеСхемыЗапроса("&Окончание") ;
ИсточникПродажи.Источник.Параметры[2].Выражение = Новый ВыражениеСхемыЗапроса("Месяц") ;
ИсточникПродажи.Соединения[0].ТипСоединения = ТипСоединенияСхемыЗапроса.ПравоеВнешнее;
//Указываем отбираемые поля и устанавливаем для числовых полей соответствие с полями первого запроса
ОператорВыбораПродаж.ВыбираемыеПоля.Добавить("Продажи.Период");
ВыражениеЗакупки = ОператорВыбораПродаж.ВыбираемыеПоля.Добавить("0");
ВыражениеПродажи = ОператорВыбораПродаж.ВыбираемыеПоля.Добавить("ЕСТЬNULL(Продажи.СуммаОборот, 0)");
ЗапросВыбораИзИБ.Колонки[2].Поля.Установить(1,ВыражениеЗакупки);
ЗапросВыбораИзИБ.Колонки[3].Поля.Установить(1,ВыражениеПродажи);
//Добавляем отбор
ОператорВыбораПродаж.Отбор.Добавить("НЕ Товары.ЭтоГруппа");
//Индексируем данные
ЗапросВыбораИзИБ.Индекс.Добавить(ЗапросВыбораИзИБ.Колонки[0]);
ЗапросВыбораИзИБ.Индекс.Добавить(ЗапросВыбораИзИБ.Колонки[1]);
//Устанавливаем параметры выбора данных
ОператорВыбораПродаж.ВыбиратьРазличные = Истина;
ОператорВыбораПродаж.КоличествоПолучаемыхЗаписей = 100;
////////////////
//Второй пакет запроса
ЗапросВыбораИзВТ = СхемаЗапроса.ПакетЗапросов.Добавить();
ОператорВыбрать = ЗапросВыбораИзВТ.Операторы[0];
//Устанавливаем сформированную в прошлом запросе временную таблицу как источник
Источник = ОператорВыбрать.Источники.Добавить("ТаблицаОбороты","ТаблицаОбороты");
ОператорВыбрать.ВыбираемыеПоля.Добавить("ТаблицаОбороты.Номенклатура");
ОператорВыбрать.ВыбираемыеПоля.Добавить("ТаблицаОбороты.Период");
ОператорВыбрать.ВыбираемыеПоля.Добавить("СУММА(ТаблицаОбороты.СуммаЗакупок)");
ОператорВыбрать.ВыбираемыеПоля.Добавить("СУММА(ТаблицаОбороты.СуммаПродаж)");
//Условие отбора
ОператорВыбрать.Отбор.Добавить("СУММА(ТаблицаОбороты.СуммаЗакупок) > 0");
//Устанавливаем псевдонимы колонок
ЗапросВыбораИзВТ.Колонки[0].Псевдоним = "Номенклатура";
ЗапросВыбораИзВТ.Колонки[1].Псевдоним = "Период";
ЗапросВыбораИзВТ.Колонки[2].Псевдоним = "СуммаЗакупок";
ЗапросВыбораИзВТ.Колонки[3].Псевдоним = "СуммаПродаж";
//Порядок сортировки данных
ЗапросВыбораИзВТ.Порядок.Добавить(ЗапросВыбораИзВТ.Операторы[0].Источники[0].Источник.ДоступныеПоля[0].Поля[6]);
ЗапросВыбораИзВТ.Порядок.Добавить(ЗапросВыбораИзВТ.Колонки[1]);
//Итоги запроса
ИтогНоменклатура = ЗапросВыбораИзВТ.КонтрольныеТочкиИтогов.Добавить(ЗапросВыбораИзВТ.Колонки[0]);
ИтогНоменклатура.ТипКонтрольнойТочки = ТипКонтрольнойТочкиСхемыЗапроса.ТолькоИерархия;
ЗапросВыбораИзВТ.ОбщиеИтоги =Истина;
ЗапросВыбораИзВТ.ВыраженияИтогов.Добавить(ЗапросВыбораИзВТ.Колонки[2]);
ЗапросВыбораИзВТ.ВыраженияИтогов.Добавить(ЗапросВыбораИзВТ.Колонки[3]);
////////////////
//Последний запрос пакета - удаление временной таблицы
ЗапросУничтоженияВТ = СхемаЗапроса.ПакетЗапросов.Добавить(Тип("ЗапросУничтоженияТаблицыСхемыЗапроса"));
ЗапросУничтоженияВТ.ИмяТаблицы = "ТаблицаОбороты";
// ДАЛЕЕ ЕСЛИнам необходимо этот запрос модифицировать дальше в зависимости от настроек.
// Рассмотрим несколько примеров модификация нашего пакета из 3х запросов:
// Пример 1. Допустим, у нас есть переменные "Организация" и "Склад". И в случае, если они заполнены, нам необходимо добавить в отбор данных условия на эти переменные.
Если ЗначениеЗаполнено(Организация) Тогда
ОператорВыбораЗакупок.Отбор.Добавить("Закупки.Организация = &Организация");
ОператорВыбораПродаж.Отбор.Добавить("Продажи.Организация = &Организация");
КонецЕсли;
Если ЗначениеЗаполнено(Склад) Тогда
ОператорВыбораЗакупок.Отбор.Добавить("Закупки.Склад = &Склад");
ОператорВыбораПродаж.Отбор.Добавить("Продажи.Склад = &Склад");
КонецЕсли;
// Пример 2. Нам нужно отобрать товары, для которых последняя цена выше 1000руб. Т.е. необходимо
// 1. Добавить в текст запроса выбор во временную таблицу из регистра цен номенклатуры, по которой цены выше 1000руб.
// 2. Добавить при выборе данных условия по этой временной таблице в оба запроса выбора данных (закупки и продажи).
// Как вклиниваться в текстовый запрос для выполнения этих действий, вы пожете представить самостоятельно.
// Программно мы просто добавляем строки кода:
//Добавляем временную таблицу
ЗапросИзРегистраЦен = СхемаЗапроса.ПакетЗапросов.Добавить();
//Настраиваем временную таблицу
ЗапросИзРегистраЦен.ТаблицаДляПомещения = "ВТ_ЦеныНоменклатуры";
ОператорВыбрать = ЗапросИзРегистраЦен.Операторы[0];
Источник = ОператорВыбрать.Источники.Добавить("РегистрСведений.ЦеныНоменклатуры.СрезПоследних","ЦеныНоменклатурыСрезПоследних");
ОператорВыбрать.ВыбираемыеПоля.Добавить("ЦеныНоменклатурыСрезПоследних.Номенклатура");
ОператорВыбрать.Отбор.Добавить("ЦеныНоменклатурыСрезПоследних.Цена > &Цена");
//Сдвигаем новую табличку перед запросами выбора данных
СхемаЗапроса.ПакетЗапросов.Сдвинуть(СхемаЗапроса.ПакетЗапросов.Индекс(ЗапросИзРегистраЦен),0);
//Добавляем условия в исходные запросы
ОператорВыбораЗакупок.Отбор.Добавить("Закупки.Номенклатура В (ВЫБРАТЬ ВТ_ЦеныНоменклатуры.Номенклатура ИЗ ВТ_ЦеныНоменклатуры КАК ВТ_ЦеныНоменклатуры)");
ОператорВыбораПродаж.Отбор.Добавить("Продажи.Номенклатура В (ВЫБРАТЬ ВТ_ЦеныНоменклатуры.Номенклатура ИЗ ВТ_ЦеныНоменклатуры КАК ВТ_ЦеныНоменклатуры)");
// Еще один небольшой пример использования схемы запроса. Формирование запроса, выполняющего поиск задвоенных значений предопределенных данных.
// Без обращения к метаданным формирует один общий запрос ко всем справочникам, планам счетов, ПВХ, ПВР вцелом по конфигурации.
СхемаЗапроса = Новый СхемаЗапроса;
КоллекцияОператоры = СхемаЗапроса.ПакетЗапросов[0].Операторы;
Для каждого ГруппаТаблиц Из СхемаЗапроса.ПакетЗапросов[0].ДоступныеТаблицы Цикл
Если ГруппаТаблиц.Представление = "Справочники"
ИЛИ ГруппаТаблиц.Представление = "ПланыСчетов"
ИЛИ ГруппаТаблиц.Представление = "ПланыВидовРасчета"
ИЛИ ГруппаТаблиц.Представление = "ПланыВидовХарактеристик" Тогда
Для каждого Таблица Из ГруппаТаблиц.Состав Цикл
Для каждого ПолеТаблицы Из Таблица.Поля Цикл
Если ПолеТаблицы.Имя = "ИмяПредопределенныхДанных" Тогда
НовыйОператор = КоллекцияОператоры.Добавить();
НовыйИсточник = НовыйОператор.Источники.Добавить(Таблица,"СправочникИмя");
НовыйОператор.ВыбираемыеПоля.Добавить(""""+Таблица.Имя+"""");
НовыйОператор.ВыбираемыеПоля.Добавить("КОЛИЧЕСТВО(РАЗЛИЧНЫЕ СправочникИмя.ИмяПредопределенныхДанных)" );
НовыйОператор.Группировка.Добавить("СправочникИмя.ИмяПредопределенныхДанных");
НовыйОператор.Отбор.Добавить("СправочникИмя.Предопределенный");
НовыйОператор.Отбор.Добавить("КОЛИЧЕСТВО(РАЗЛИЧНЫЕ СправочникИмя.Ссылка) > 1");
Продолжить;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Категория:
Запросы Как принудительно завершить бизнес-процесс и задачи? Стандартная механика обеспечивает автоматическое завершение бизнес-процесса, когда он достигает точки завершения и все задачи по нему выполнены.
Однако иногда может потребоваться принудительно завершить бизнес-процесс, не дожидаясь, пока он дойдет до точки завершения.
Для этого необходимо установить свойство Завершен бизнес-процесса равным Истина:
Код 1C v 8.х БизнесПроцесс.Завершен = Истина;
БизнесПроцесс.Записать();
Далее нужно отметить все задачи по этому бизнес-процессу как выполненные.
1. Отобрать задачи по бизнес-процессу можно с помощью запроса вида:
2. После чего каждой из отобранных задач нужно установить свойство Выполнена равным Истина:
Код 1C v 8.х ТекущаяЗадача.Выполнена = Истина;
ТекущаяЗадача.Записать();
Рекомендуется выполнять запись бизнес-процесса и задач в транзакции , чтобы избежать возможного расхождения бизнес-процесса и связанных с ним задач.
Код 1C v 8.х Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОСН_Задача.Ссылка,
| ОСН_Задача.Дата,
| ОСН_Задача.БизнесПроцесс,
| ОСН_Задача.ТочкаМаршрута,
| ОСН_Задача.Пользователь,
| ОСН_Задача.Подразделение,
| ОСН_Задача.БизнесПроцесс.ДокументДоставки
|ИЗ
| Задача.ОСН_Задача КАК ОСН_Задача
|ГДЕ
| ОСН_Задача.БизнесПроцесс.ДокументДоставки = &ДокументДоставки";
Запрос.УстановитьПараметр("ДокументДоставки", ВыбранныйДокумент);
Результат = Запрос.Выполнить();
Выборка = Результат.Выгрузить();
ТекПозиция = 0;
Для каждого СтрокаЗапроса из Выборка Цикл
ОбработкаПрерыванияПользователя();
ТекПозиция = ТекПозиция + 1;
Состояние("Выполнено " + Окр(ТекПозиция / РезультатТаблица.Количество() * 100) + "%");
//Завешим Задачу
ОбъектЗадача = СтрокаЗапроса.Ссылка.ПолучитьОбъект();
ОбъектЗадача.Выполнена = Истина;
ОбъектЗадача.Записать();
//Если необходимо то Завершим и Бизнес Процесс
БизнесПроцесс = СтрокаЗапроса.БизнесПроцесс.ПолучитьОбъект();
БизнесПроцесс.Завершен = Истина;
БизнесПроцесс.Записать();
КонецЦикла;
Код 1C v 8.х Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| CRM_Задача.Ссылка,
| CRM_Задача.Дата,
| CRM_Задача.БизнесПроцесс,
| CRM_Задача.ТочкаМаршрута,
| CRM_Задача.Пользователь,
| CRM_Задача.Подразделение,
| CRM_Задача.БизнесПроцесс.ДокументДоставки
|ИЗ
| Задача.CRM_Задача КАК CRM_Задача
|ГДЕ
| CRM_Задача.Выполнена = ЛОЖЬ
| И CRM_Задача.Дата < &Дата";
Запрос.УстановитьПараметр("Дата", Дата("07.09.2012 0:00:00"));
Результат = Запрос.Выполнить();
Выборка = Результат.Выгрузить();
ТекПозиция = 0;
Для каждого СтрокаЗапроса из Выборка Цикл
ОбработкаПрерыванияПользователя();
ТекПозиция = ТекПозиция + 1;
Состояние("Выполнено " + Окр(ТекПозиция / РезультатТаблица.Количество() * 100) + "%");
//Завешим Задачу
ОбъектЗадача = СтрокаЗапроса.Ссылка.ПолучитьОбъект();
ОбъектЗадача.ВыполнитьЗадачу();
//Если необходимо то Завершим и Бизнес Процесс
Если НЕ СтрокаЗапроса.Ссылка.БизнесПроцесс.Завершен Тогда
БизнесПроцесс = СтрокаЗапроса.Ссылка.БизнесПроцесс.ПолучитьОбъект();
БизнесПроцесс.Завершен = Истина;
БизнесПроцесс.Записать();
КонецЕсли;
КонецЦикла;
Категория:
Бизнес-процессы Условия сравнения и проверки в Запросах. Отбор не заполненного значения Как задать отбор по Типу документа?
Как указать условие для отбора не определенного значения?
Как в языке запросов 1С отобрать не заполненное значение?
Какое условие указать в запросе после ключевого слова «ГДЕ», когда нужно сделать отбор по не заполненным полям?
Код 1C v 8.х Запрос.Текст =
"ВЫБРАТЬ
| усЕдиницыХранения.Ссылка
|ИЗ
| Справочник.усЕдиницыХранения КАК усЕдиницыХранения"
// Пример 1. сравнение с не заполненным булевым значением:
|ГДЕ
| усЕдиницыХранения.РазрешитьОтборИзРезервнойЗоны = Ложь
// Пример 2. но если это булево определено, то лучше так: // условие на отрицательное булево:
|ГДЕ
| НЕ усЕдиницыХранения.РазрешитьОтборИзРезервнойЗоны
// Пример 3. выборка по условию не заполненного поля, имеющего тип "справочник конкретного типа"
|ГДЕ
| усЕдиницыХранения.АктивнаяОбластьОтбора = ЗНАЧЕНИЕ(Справочник.усОбластиОтбора.ПустаяСсылка)
// Пример 3а. выборка по условию не заполненного поля, имеющего тип "документ конкретного типа"
|ГДЕ
| НашРегистрСведений.Документ = ЗНАЧЕНИЕ(Документ.НашДокумент.ПустаяСсылка)
// Пример 3б. выборка по условию не заполненного поля, имеющего тип "документы разных типов" (составное поле)
|ГДЕ
| (НашРегистрСведений.Документ = ЗНАЧЕНИЕ(Документ.НашДокумент1.ПустаяСсылка)
| ИЛИ НашРегистрСведений.Документ = ЗНАЧЕНИЕ(Документ.НашДокумент2.ПустаяСсылка)
| ИЛИ ...(и т.д. - последовательно перечисляем условия для всех возможных типов этого составного поля))
// Пример 4. или наоборот, если нужно выбрать заполненное значение типа "строка", то поможет условие:
|ГДЕ
| усЕдиницыХранения.Наименование > """"
// Пример 5. если нужно выбрать документы конкретного типа, при составном типе данных, например в регистре "ВыполняемыеЗадания" ресурс "Задание" имеет составной тип, среди значений которого возможен документ "Отбор"
|ГДЕ
| ВЫРАЗИТЬ(РегистрСведенийВыполняемыеЗадания.Задание КАК Документ.Отбор) ССЫЛКА Документ.Отбор
// Пример 5а. Еще аналогичный пример, когда нужно выбрать документы конкретного типа
| ВЫБОР
| КОГДА ВЫРАЗИТЬ(агСоответствиеДокументов.ДокументБУ КАК Документ.ПоступлениеТоваровУслуг) ССЫЛКА Документ.ПоступлениеТоваровУслуг
| ТОГДА ""ПоступлениеТоваровУслуг""
| КОГДА ВЫРАЗИТЬ(агСоответствиеДокументов.ДокументБУ КАК Документ.РеализацияТоваровУслуг) ССЫЛКА Документ.РеализацияТоваровУслуг
| ТОГДА ""РеализацияТоваровУслуг""
| ИНАЧЕ """"
| КОНЕЦ КАК ВидДокумента
// Пример 6. выбор по условию не определенного значения:
|ГДЕ
| СохраненныеНастройки.Пользователь = НЕОПРЕДЕЛЕНО
// Пример 7. выбор по виду движения "Приход" регистра накопления, "Расход" - аналогично):
|ГДЕ
| РегТоварыВРознице.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
// Пример 8. Как в запросе указать, что выполнять запрос не нужно (например, нужно программно в зависимости от какого-то
// условия вернуть пустой результат запроса -
// Запрос.Текст = СтрЗаменить(Запрос.Текст, "ГДЕ Док.Ссылка = &ДокументСсылка", "ГДЕ ЛОЖЬ");).
// Для этого достаточно добавить условие "Где Ложь".
// Кстати, независимо от объема запрашиваемых в выборке данных, такой запрос будет выполнен мгновенно.
|ГДЕ ЛОЖЬ
// Пример 9. Проверка на то, что результат выполнения запроса содержит данные:
Если НЕ Запрос.Выполнить().Пустой() Тогда
// Пример 10. выбор по условию не заполненной даты:
|ГДЕ
| тбСтроки.ДатаОтмены = ДАТАВРЕМЯ(1, 1, 1)
источник Категория:
Запросы Как в запросе отобрать значения по Типу? Для того, чтобы определить
отобрать по типу значения в запросе нужно использовать логический оператор "ССЫЛКА". Примером может служить вот такой фрагмент запроса из типовой конфигурации 1С:
Код 1C v 8.х Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ХозрасчетныйОстатки.Субконто1 КАК Покупатель
|ИЗ
| РегистрБухгалтерии.Хозрасчетный.Остатки(
| &Период,
| Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.НДСНачисленныйПоОтгрузке),
| ,
| Организация = &Организация
| И Субконто2 ССЫЛКА Документ.РеализацияТоваровУслуг
| И Субконто1 В (&СписокПокупателей)
| И ВЫРАЗИТЬ(Субконто2 КАК Документ.РеализацияТоваровУслуг).ВидОперации =
| &ОперацияОтгрузка) КАК ХозрасчетныйОстатки";
В данном примере используется проверка, что субконто 2 содержит тип значения ссылки на документ Реализации товаров и услуг, чтобы потом уверенно использовать реквизит вид операции.
Категория:
Запросы Как в запросе отобрать битые ссылки, поиск Битых Ссылок Когда объект был удален непосредственно, то все ссылки на него в справочниках, в документах, в регистрах стали битыми и отображаются следующим образом:
<Объект не найден> (16:bca8000c6efdd52111d8eaba7c9706eb)
Битая ссылка не является пустой. Т.е. метод Пустая() возвращает Ложь. Определить, что ссылка битая можно так:
Код 1C v 8.х Если Ссылка.ПолучитьОбъект() = Неопределено Тогда
//битая ссылка
КонецЕсли;
// или так (НО ненадежно):
Если Лев(СокрЛП(Ссылка),18) = "<Объект не найден>" Тогда
Код 1C v 8.х // Еще вариант (действует для обьектов, которые имеют ссылку)
Попытка
обьект=Ссылка.Ссылка;
Исключение
сообщить("битая");
КонецПопытки;
И последний вариант для проверки в запросах:
ГДЕ Объект.РеквизитОбъекта ЕСТЬ NULL И Не Объект=&ПустаяСсылкаОбъекта
Ниже дана программа для удаления записей регистров, у которых регистратор - битая ссылка, т.е. не существует в базе.
Код 1C v 8.х Процедура УдалениеБитыхСсылок(ИмяРегистра,ТипРегистра,ТипРегистраЗ)
МенеджерРегистра = ТипРегистра[ИмяРегистра];
Запрос = Новый Запрос("
|ВЫБРАТЬ Регистратор
|ИЗ "+ТипРегистраЗ+"."+ИмяРегистра+"
|ГДЕ Регистратор.Ссылка ЕСТЬ NULL И НЕ Регистратор = &ПустаяСсылкаДокумента");
Запрос.УстановитьПараметр("ПустаяСсылкаДокумента",Неопределено);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Набор = ТипРегистра[ИмяРегистра].СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(Выборка.Регистратор);
Набор.Записать();
ОбработкаПрерыванияПользователя();
Состояние(""+ТипРегистра+" "+ИмяРегистра);
КонецЦикла;
КонецПроцедуры
Процедура КнопкаВыполнитьНажатие(Кнопка)
Для Каждого пРегистр из Метаданные.РегистрыСведений Цикл
Подчинен = (пРегистр.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору);
Если Подчинен Тогда
УдалениеБитыхСсылок(пРегистр.Имя,РегистрыСведений,"РегистрСведений")
КонецЕсли;
КонецЦикла;
Для Каждого пРегистр из Метаданные.РегистрыБухгалтерии Цикл
УдалениеБитыхСсылок(пРегистр.Имя,РегистрыБухгалтерии,"РегистрБухгалтерии")
КонецЦикла;
Для Каждого пРегистр из Метаданные.РегистрыРасчета Цикл
УдалениеБитыхСсылок(пРегистр.Имя,РегистрыРасчета,"РегистрРасчета")
КонецЦикла;
Для Каждого пРегистр из Метаданные.РегистрыНакопления Цикл
УдалениеБитыхСсылок(пРегистр.Имя,РегистрыНакопления,"РегистрНакопления")
КонецЦикла;
КонецПроцедуры
Категория:
Запросы Как указать в запросе пустую ссылку, отбор по Пустой Ссылке Код 1C v 8.х // В запросах для версии 8.0 так:
...
|ГДЕ Поле = &ПустаяСсылка";
Запрос.УстановитьПараметр("ПустаяСсылка",Справочники.Номенклатура.ПустаяСсылка());
// В запросах для версии 8.1 и более так:
...
|ГДЕ Поле = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)";
...
|ГДЕ CRM_Задача.ДокументДоставки <> Значение(Документ.Доставка.ПустаяСсылка)
Когда в запросе нужно отобрать документы с пустыми ссылками:
Код 1C v 8.х ...
|ГДЕ ВзаиморасчетыСРаботникамиОрганизации.Регистратор.ПерерасчитываемыйДокумент.Ссылка ЕСТЬ NULL";
Когда в запросе нужно отобрать документы с НЕ пустыми ссылками:
Код 1C v 8.х ...
|ГДЕ СделкаВзаиморасчета.Сделка.Ссылка ЕСТЬ НЕ NULL ";
Категория:
Запросы Как в журнале документов отобрать только документы "ПриемНаРаботу"? Код 1C v 8.2 УП ЭлементОтбора = ИсторияЛимитовИПорогов.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Абонент");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
ЭлементОтбора.ПравоеЗначение = Объект.Ссылка;
Код 1C v 8.х ЖурналДокументовСписок.Отбор.ВидДокумента.Установить(Метаданные.Документы.ПриемНаРаботу);
Категория:
Список Справочника, Документов, Регистров Поле выбора ~ Как отобрать значения выводящиеся в список выбора у элемента формы поле выбора? Использование отбора:
Функционал, который используется для интерактивного отбора в списках, можно использовать и для отбора программным способом.
Для этого нужно для
события НачалоВыбора соответствующего поля ввода определить процедуру обработки и внутри процедуры программно устанавить отбор для списка.
Далее следует пример процедуры обработки
события НачалоВыбора для поля ввода
СтатьяПДР . Реквизит (и поле ввода, соответственно)
СтатьяПДР имеет тип
СправочникСсылка.ПрочиеДоходыИРасходы . Для списка справочника «Прочие доходы и расходы» устанавливается отбор по реквизиту «Вид прочих доходов и расходов» со значением «Прочие внереализационные доходы (расходы)».
Код 1C v 8.х Процедура СтатьяПДРНачалоВыбора(Элемент, СтандартнаяОбработка)
ФормаВыбора = Справочники.ПрочиеДоходыИРасходы.ПолучитьФормуВыбора(, Элемент);
ЭлементОтбораВидПДР = ФормаВыбора.Отбор.ВидПрочихДоходовИРасходов;
Если ЭлементОтбораВидПДР <> Неопределено Тогда
ЭлементОтбораВидПДР.ВидСравнения = ВидСравнения.Равно;
ЭлементОтбораВидПДР.Значение = Перечисления.ВидыПрочихДоходовИРасходов.ПрочиеВнереализационныеДоходыРасходы;
ЭлементОтбораВидПДР.Использование = Истина;
КонецЕсли;
ФормаВыбора.ЭлементыФормы.СправочникСписок.НастройкаОтбора.ВидПрочихДоходовИРасходов.Доступность = Ложь;
ФормаВыбора.Открыть();
СтандартнаяОбработка = Ложь;
КонецПроцедуры
Обратите внимание на строку кода:
Код 1C v 8.х ФормаВыбора.ЭлементыФормы.СправочникСписок.НастройкаОтбора.ВидПрочихДоходовИРасходов.Доступность = Ложь;
Она закрывает доступ к настройке отбора «Вид прочих доходов и расходов». Таким образом, пользователь не может отключить заданный программно отбор и имеет возможность сделать выбор значения только из ограниченного списка.
Внутри процедуры обработки события НачалоВыбора параметру СтандартнаяОбработка нужно обязательно присвоить значение Ложь. В противном случае будет открыт и ограниченный список, и стандартный список, а это, конечно, не входит в наши планы.
В следующем примере для поля ввода СчетДт типа ПланСчетовСсылка.Хозрасчетный
устанавливается отбор в виде списка счетов . Список счетов предварительно формируется с помощью запроса.
Код 1C v 8.х Процедура СчетДтНачалоВыбора(Элемент, СтандартнаяОбработка)
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Хозрасчетный.Ссылка
|ИЗ
| ПланСчетов.Хозрасчетный КАК Хозрасчетный
|ГДЕ
| Хозрасчетный.Родитель В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.Материалы))
| И Хозрасчетный.ЗапретитьИспользоватьВПроводках = ЛОЖЬ";
СписокСчетов = Новый СписокЗначений;
СписокСчетов.ЗагрузитьЗначения(Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка"));
ФормаВыбора = ПланыСчетов.Хозрасчетный.ПолучитьФормуВыбора(, Элемент);
ЭлементОтбораСсылка = ФормаВыбора.Отбор.Ссылка;
Если ЭлементОтбораСсылка <> Неопределено Тогда
ЭлементОтбораСсылка.ВидСравнения = ВидСравнения.ВСписке;
ЭлементОтбораСсылка.Значение = СписокСчетов;
ЭлементОтбораСсылка.Использование = Истина;
КонецЕсли;
ФормаВыбора.ЭлементыФормы.Список.НастройкаОтбора.Ссылка.Доступность = Ложь;
ФормаВыбора.Открыть();
СтандартнаяОбработка = Ложь;
КонецПроцедуры
Использование выбора из списка:
Выбор значения
Перечисления обычно осуществляется из маленького списка. Но даже если включить выбор из формы (это делается с помощью свойства «Быстрый выбор» поля ввода), функционал отбора для перечислений все равно неприменим.
В таком случае подходящий способ ограничения списка выбора - использование метода формы ВыбратьИзСписка. Аналогично первому способу, необходимо определить процедуру обработки события НачалоВыбора для поля ввода значения. В следующем примере для поля ввода ВидПДР типа ПеречислениеСсылка.ВидыПрочихДоходовИРасходов программно устанавливается ограниченный список выбора.
Код 1C v 8.х Процедура ВидПДРНачалоВыбора(Элемент, СтандартнаяОбработка)
ВидыПДР = Новый СписокЗначений;
ВидыПДР.Добавить(Перечисления.ВидыПрочихДоходовИРасходов.ПрочиеВнереализационныеДоходыРасходы);
ВидыПДР.Добавить(Перечисления.ВидыПрочихДоходовИРасходов.ПрочиеОперационныеДоходыРасходы);
ВыбранныйЭлемент = ВыбратьИзСписка(ВидыПДР, Элемент, ВидыПДР.НайтиПоЗначению(Элемент.Значение));
Если ВыбранныйЭлемент <> Неопределено Тогда
Элемент.Значение = ВыбранныйЭлемент.Значение;
КонецЕсли;
СтандартнаяОбработка = Ложь;
КонецПроцедуры
Результат работы процедуры показан на рисунке. Метод ВыбратьИзСписка открывает маленький список с набором значений, переданных в процедуру в первом параметре (в примере - список значений ВидыПДР).
Пример ограничения списка выбора для перечисления в 1С 8
Пример для других агрегатных типов:
Код 1C v 8.х Процедура СчетКтНачалоВыбора(Элемент, СтандартнаяОбработка)
СчетаКт = Новый СписокЗначений;
СчетаКт.Добавить(ПланыСчетов.Хозрасчетный.РасчетыСПоставщиками);
СчетаКт.Добавить(ПланыСчетов.Хозрасчетный.РасчетыСПодотчетнымиЛицами);
СчетаКт.Добавить(ПланыСчетов.Хозрасчетный.РасчетыСПрочимиПоставщикамиИПодрядчиками);
СчетаКт.Добавить(ПланыСчетов.Хозрасчетный.РасчетыПоТекущимОперациям);
СчетаКт.Добавить(ПланыСчетов.Хозрасчетный.ПрочиеДоходы);
ВыбранныйЭлемент = ВыбратьИзСписка(СчетаКт, Элемент, СчетаКт.НайтиПоЗначению(Элемент.Значение));
Если ВыбранныйЭлемент <> Неопределено Тогда
Элемент.Значение = ВыбранныйЭлемент.Значение;
КонецЕсли;
СтандартнаяОбработка = Ложь;
КонецПроцедуры
Категория:
Работа с Формой (Диалог) и её элементами Как программно открыть и выбрать элемент справочника, выбор элемента справочника? Просто открыть:
Код 1C v 8.х // Получить форму выбора справочника как подчиненную форме документа
ФормаСписка = Справочники.Номенклатура.ПолучитьФормуСписка( , ЭтаФорма);
// Открыть полученную форму
ФормаСписка.Открыть();
Открыть для выбора элемента:
Код 1C v 8.х ФормаВыбора = Справочники.Номенклатура.ПолучитьФормуВыбора( , ЭтаФорма);
ФормаВыбора.Заголовок = "Выберите товар!";
Выбрано = ФормаВыбора.ОткрытьМодально();
Открыть справочник для выбора элемента и установить отбор:
Код 1C v 8.х // Если Отобрать = Истина, то откроется выборка справочника без элементов у которых ГруппыПользователей.ВсеПользователи
Если Отобрать Тогда
ФормаВыбора = Справочники.ГруппыПользователей.ПолучитьФормуВыбора();
ФормаВыбора.Отбор.Ссылка.Установить(Справочники.ГруппыПользователей.ВсеПользователи);
ФормаВыбора.Отбор.Ссылка.ВидСравнения = ВидСравнения.НеРавно;
Иначе
ФормаВыбора = Справочники.Пользователи.ПолучитьФормуВыбора();
КонецЕсли;
// укажем что выбирать только элементы
ФормаВыбора.ПараметрВыборГруппИЭлементов = ИспользованиеГруппИЭлементов.Элементы;
ВыбранноеЗначение = ФормаВыбора.ОткрытьМодально();
Примеры использования событий(Вывели на форму поле елемента справочника, в его свойствах есть события)
Код 1C v 8.х Процедура ПолеВводаНачалоВыбора(Элемент, СтандартнаяОбработка)
// Запретить стандартную обработку.
СтандартнаяОбработка = Ложь;
// Получить форму выбора справочника как подчиненную полю ввода.
ФормаВыбора = Справочники.Номенклатура.ПолучитьФормуВыбора( , Элемент);
// Открыть полученную форму
ФормаВыбора.Открыть();
КонецПроцедуры
Процедура ПолеВводаОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
// Отключить стандартную обработку (при необходимости).
СтандартнаяОбработка = Ложь;
ПолученноеЗначение = ВыбранноеЗначение;
// Дальнейшая обработка значения.
КонецПроцедуры
Категория:
Справочники Как найти битую ссылку? Категория:
Полезные, Универсальные Функции Процедура действие отобрать для кнопки Можно на командной панели формы сделать Подменю Отбор и в Имени каждого пункта указать значение отбора, а действие одна и таже процедура:
Код 1C v 8.х Процедура ДействиеОтобратьДокументы(Кнопка)
ДокументСписок.Отбор.Сбросить();
ДокументСписок.Отбор.Комментарий.ВидСравнения=ВидСравнения.Содержит;
ДокументСписок.Отбор.Комментарий.Значение=Кнопка.Имя;
ДокументСписок.Отбор.Комментарий.установить();
КонецПроцедуры
Категория:
Список Справочника, Документов, Регистров