+14
Как одним запросом выбрать документы всех видов?
Используя метаданные и возможность объединения запросов:
Код 1C v 8.х
Запрос=Новый Запрос;
Текст="";
Для Каждого Документ Из Метаданные.Документы Цикл
Текст=Текст+"ВЫБРАТЬ Ссылка ИЗ Документ."+Документ.Имя+" ОБЪЕДИНИТЬ ";
КонецЦикла;
Запрос.Текст=Лев(Текст,СтрДлина(Текст)-СтрДлина(" ОБЪЕДИНИТЬ "));
Выборка=Запрос.Выполнить().Выбрать();
Пример от Ненавижу 1С
Код 1C v 8.х
ТекстЗапроса = "";
Для каждого Вид Из Метаданные.Документы Цикл
Если ТекстЗапроса<>"" Тогда
ТекстЗапроса=ТекстЗапроса+"
|ОБЪЕДИНИТЬ ВСЕ";
КонецЕсли;
ТекстЗапроса = ТекстЗапроса+"
|ВЫБРАТЬ Ссылка
|ИЗ Документ."+Вид.Имя;
КонецЦикла;
Запрос = Новый Запрос(ТекстЗапроса);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Ссылка);
КонецЦикла;
Выбрать все документы запросом |
Я |
27.02.16 — 14:11
Здравствуйте! Есть запрос, в котором я перебираю все документы. Столкнулся с такой проблемой: в документах необходимо выбрать «Ответственного», причем в некоторых документах такого реквизита может не быть. Как можно задать в запросе проверку, что если реквизита нет, то вывести пустую строку, а если реквизит есть, то вывести данные.
Запрос = Новый Запрос;
Запрос.УстановитьПараметр(«ПустаяСтрока», «»);
Текст = «»;
Для Каждого Документ Из Метаданные.Документы Цикл
Текст = Текст + «ВЫБРАТЬ
| » + Документ.Имя + «.Ссылка КАК Документ,
| » + Документ.Имя + «.Номер КАК Номер,
| » + Документ.Имя + «.Дата КАК Дата//,
//| ВЫБОР
//| КОГДА » + Документ.Имя + «.Ответственный
//| ТОГДА » + Документ.Имя + «.Ответственный
//| ИНАЧЕ
//| КОНЕЦ
|ИЗ
| Документ.» + Документ.Имя + » КАК » + Документ.Имя + » ОБЪЕДИНИТЬ «;
КонецЦикла;
Запрос.Текст = Лев(Текст, СтрДлина(Текст) — СтрДлина(» ОБЪЕДИНИТЬ «));
Выборка = Запрос.Выполнить().Выбрать();
1 — 27.02.16 — 14:39
Выбор Когда ТипЗначения(Документ) = Тип(«Документ без реквизита») Тогда «Пусто»
как-то так
2 — 27.02.16 — 14:43
(0) Это следует делать при конструировании текста запроса.
3 — 27.02.16 — 15:42
(0)в запросе через точку ссылка.реквизит , если будет рекв то заполнено, если нет то NULL. Но судя по коду если уже начали собирать запрос циклом, то можно как в (1)
4 — 27.02.16 — 15:44
Выбор когда Док.Ссылка Ссылка Документ.Накладная Тогда Документ.Ответственный Иначе «» конец Как Ответственный
вроде так можно
5 — 27.02.16 — 15:58
(0) Если проблема именно в автоматическом определении документов то смотри «Метаданные».
Дословно не помню, что-то вроде такой конструкции
Для Каждого Метадок из Метаданные.Документы Цикл
Если Метадок.Реквизиты.Найти("Ответственный") Тогда
Сообщить(Метадок.Имя);
КонецЕсли;
КонецЦикла;
Мог в каждой строке ошибиться, это для представления, как делать…
6 — 27.02.16 — 16:07
(5) Да, все верно, такое есть и можно сделать так:
Для Каждого Документ Из Метаданные.Документы Цикл
Если Документ.Реквизиты.Найти(«Ответственный») = Неопределено Тогда
Текст = Текст + «ВЫБРАТЬ
| » + Документ.Имя + «.Ссылка КАК Документ,
| » + Документ.Имя + «.Номер КАК Номер,
| » + Документ.Имя + «.Дата КАК Дата,
| &ПустаяСтрока КАК Ответственный
|ИЗ
| Документ.» + Документ.Имя + » КАК » + Документ.Имя + »
|ГДЕ
| » + Документ.Имя + «.Дата МЕЖДУ &НачалоПериода И &КонецПериода ОБЪЕДИНИТЬ «;
Иначе
Текст = Текст + «ВЫБРАТЬ
| » + Документ.Имя + «.Ссылка КАК Документ,
| » + Документ.Имя + «.Номер КАК Номер,
| » + Документ.Имя + «.Дата КАК Дата,
| » + Документ.Имя + «.Ответственный КАК Ответственный
|ИЗ
| Документ.» + Документ.Имя + » КАК » + Документ.Имя + »
|ГДЕ
| » + Документ.Имя + «.Дата МЕЖДУ &НачалоПериода И &КонецПериода ОБЪЕДИНИТЬ «;
КонецЕсли;
КонецЦикла;
Но надо «Ответственного» выбрать одним запросом…
7 — 27.02.16 — 16:10
(6) Можно не конструировать запрос в строковой переменной.
Напиши запрос для одного документа, а потом в цикле аккуратно делай
Текст = Заменить(Текст, «Документ.Накладная», «Документ.» + Документ.Имя);
8 — 27.02.16 — 16:22
(7) Идея отличная, но воспользоваться не могу. Нужно собирать запрос именно по метаданным, чтобы к разным конфигурациям подходил
9 — 27.02.16 — 16:39
(6) Задача решена. Что не так?
kosts
10 — 27.02.16 — 17:05
(8) Вот что я имел ввиду в (7). Как вариант, просто нагляднее. Для простого запроса может лишнее, для сложных запросов полезнее.
Для Каждого Документ Из Метаданные.Документы Цикл
Текст = "ВЫБРАТЬ
| Документ.Ссылка КАК Документ,
| Документ.Номер КАК Номер,
| Документ.Дата КАК Дата,
| &Ответственный КАК Ответственный
|ИЗ
| Документ.Накладная КАК Документ
|ГДЕ
| Документ.Дата МЕЖДУ &НачалоПериода И &КонецПериода ";
Текст = Заменить(Текст, "Документ.Накладная", "Документ." + Документ.Имя);
Если Документ.Реквизиты.Найти("Ответственный") <> Неопределено Тогда
Текст = Заменить(Текст, "&Ответственный", "Документ.Ответственный");
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + Текст + " ОБЪЕДИНИТЬ ВСЕ ";
КонецЦикла;
Как выбрать и упорядочить документы за период в 1С
&НаСервере
Процедура КакВыбратьИУпорядочитьДокументыЗаПериодНаСервере()
// найдём все документы поступления за 2020 год
// упорядочив их по возрастанию даты
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Ссылка
|ИЗ
| Документ.ПоступлениеТоваров КАК ПоступлениеТоваров
|ГДЕ
| Дата МЕЖДУ &НачДата И &КонДата
|УПОРЯДОЧИТЬ ПО
| Дата ВОЗР";
Запрос.УстановитьПараметр("НачДата", '20200101');
Запрос.УстановитьПараметр("КонДата", '20201231');
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДокументов = РезультатЗапроса.Выбрать();
Пока ВыборкаДокументов.Следующий() Цикл
Сообщить(ВыборкаДокументов.Ссылка);
КонецЦикла;
КонецПроцедуры
Как найти документ по номеру в 1С
&НаСервере
Процедура КакНайтиДокументПоНомеруНаСервере()
// найдём поступление № А-000000001 за 2020 год
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Ссылка
|ИЗ
| Документ.ПоступлениеТоваров КАК ПоступлениеТоваров
|ГДЕ
| Дата МЕЖДУ &НачДата И &КонДата И
| Номер = &ВыбНомер";
Запрос.УстановитьПараметр("НачДата", '20200101');
Запрос.УстановитьПараметр("КонДата", '20201231');
Запрос.УстановитьПараметр("ВыбНомер", "А-000000001");
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДокументов = РезультатЗапроса.Выбрать();
Если ВыборкаДокументов.Следующий() Тогда
Сообщить(ВыборкаДокументов.Ссылка);
Иначе
Сообщить("Документ с таким номером не существует!");
КонецЕсли;
КонецПроцедуры
Как найти документы по реквизиту в 1С
&НаСервере
Процедура КакНайтиДокументПоРеквизитуНаСервере()
// найдём все документы поступления
// от поставщика ООО "Ромашка"
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Ссылка,
| Поставщик
|ИЗ
| Документ.ПоступлениеТоваров КАК ПоступлениеТоваров
|ГДЕ
| Поставщик = &ВыбПоставщик
|УПОРЯДОЧИТЬ ПО
| Дата ВОЗР";
Запрос.УстановитьПараметр(
"ВыбПоставщик",
Справочники.Поставщики.НайтиПоНаименованию("ООО ""Ромашка""")
);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДокументов = РезультатЗапроса.Выбрать();
Пока ВыборкаДокументов.Следующий() Цикл
Сообщить(
Строка(ВыборкаДокументов.Ссылка) + " " +
ВыборкаДокументов.Поставщик
);
КонецЦикла;
КонецПроцедуры
Как выбрать все документы, которые не проведены и не помечены на удаление в 1С
&НаСервере
Процедура КакВыбратьВсеДокументыКоторыеНеПроведеныИНеПомеченыНаУдалениеНаСервере()
// найдём не проведенные и не помеченные на удаление
// документы поступления товаров
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Ссылка,
| Проведен,
| ПометкаУдаления
|ИЗ
| Документ.ПоступлениеТоваров КАК ПоступлениеТоваров
|ГДЕ
| Проведен = ЛОЖЬ И
| ПометкаУдаления = ЛОЖЬ
|УПОРЯДОЧИТЬ ПО
| Дата ВОЗР";
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДокументов = РезультатЗапроса.Выбрать();
Пока ВыборкаДокументов.Следующий() Цикл
Сообщить(
Строка(ВыборкаДокументов.Ссылка) + " " +
ВыборкаДокументов.Проведен + " " +
ВыборкаДокументов.ПометкаУдаления
);
КонецЦикла;
КонецПроцедуры
Как найти подчиненные документы в 1С
&НаСервере
Процедура КакНайтиПодчиненныеДокументыНаСервере()
// Рассмотрим работу с подчиненными (связанными) документами
// на примере документов: ПоступлениеТоваровУслуг и СчетФактураПолученный.
// Документ СчетФактураПолученный вводится на основании документа
// ПоступлениеТоваровУслуг, то есть счет фактура является подчиненной
// по отношению к поступлению.
// Факт подчиненности обычно (в типовых) фиксируется в самом подчиненном
// документе через табличную часть ДокументыОснования.
// Почему через табличную часть? Потому что один документ может зависеть
// (быть подчиненным) сразу от нескольких родителей (оснований).
// Пример №1.
// У нас есть ссылка на поступление товаров и услуг. Требуется найти
// счёт-фактуры, которые были введены на основании этого поступления.
// В дереве подчиненности эти фактуры будут подчинены (зависимы) от
// документа поступления.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Ссылка
|ИЗ
| Документ.СчетФактураПолученный.ДокументыОснования КАК
| СчетФактураПолученныйДокументыОснования
|ГДЕ
| СчетФактураПолученныйДокументыОснования.ДокументОснование =
| &ВыбПоступление";
Запрос.УстановитьПараметр("ВыбПоступление",
Документы.ПоступлениеТоваровУслуг.НайтиПоНомеру("А-00000005", '20200101')
);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
ПодчиненнаяФактура = ВыборкаДетальныеЗаписи.Ссылка;
Сообщить(ПодчиненнаяФактура);
КонецЦикла;
// Пример №2.
// У нас есть ссылка на счет-фактуру полученную. Требуется найти,
// документы, на основании которых она была введена (родителей).
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДокументОснование
|ИЗ
| Документ.СчетФактураПолученный.ДокументыОснования КАК
| СчетФактураПолученныйДокументыОснования
|ГДЕ
| СчетФактураПолученныйДокументыОснования.Ссылка =
| &ВыбСчетФактура";
Запрос.УстановитьПараметр("ВыбСчетФактура",
Документы.СчетФактураПолученный.НайтиПоНомеру("А-00000002", '20200101')
);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
РодительФактуры = ВыборкаДетальныеЗаписи.ДокументОснование;
Сообщить(РодительФактуры);
КонецЦикла;
КонецПроцедуры
Как перебрать (перечислить) строки табличной части документа в 1С
&НаСервере
Процедура КакПеречислитьСтрокиИзТабличнойЧастиДокументаНаСервере()
// У документа Поступление есть табличная часть 'Товары'.
// У этой табличной части есть колонки: Номенклатура, Количество,
// Сумма.
ПоступлениеСсылка =
Документы.ПоступлениеТоваров.НайтиПоНомеру(
"А-00000001", '20201231');
// перечислим строки табличной части этого документа
// при помощи объектной техники
Для Каждого Строка Из ПоступлениеСсылка.Товары Цикл
Сообщить(
Строка.Номенклатура.Наименование + " " +
Строка.Количество + " шт. " +
Строка.Сумма + " руб."
);
КонецЦикла;
// при помощи запроса
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПоступлениеТоваровТовары.Номенклатура,
| ПоступлениеТоваровТовары.Количество,
| ПоступлениеТоваровТовары.Сумма
|ИЗ
| Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровТовары
|ГДЕ
| ПоступлениеТоваровТовары.Ссылка = &ВыбПоступление";
Запрос.УстановитьПараметр("ВыбПоступление", ПоступлениеСсылка);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Сообщить(
ВыборкаДетальныеЗаписи.Номенклатура.Наименование + " " +
ВыборкаДетальныеЗаписи.Количество + " шт. " +
ВыборкаДетальныеЗаписи.Сумма + " руб."
);
КонецЦикла;
КонецПроцедуры
Как создать документ в 1С
// создадим новый документ поступление
Поступление = Документы.ПоступлениеТоваров.СоздатьДокумент();
// заполним шапку документа
Поступление.Дата = ТекущаяДата();
Поступление.Поставщик =
Справочники.Поставщики.НайтиПоНаименованию(
"ООО ""Ромашка"""
);
Поступление.Склад =
Справочники.Склады.НайтиПоНаименованию(
"Основной склад"
);
// заполним табличную часть
НоваяСтрока = Поступление.Товары.Добавить();
НоваяСтрока.Номенклатура =
Справочники.Номенклатура.НайтиПоНаименованию(
"Сапоги"
);
НоваяСтрока.Количество = 2;
НоваяСтрока.Сумма = 3000;
Как записать документ в 1С
Поступление.Записать(РежимЗаписиДокумента.Запись);
Как провести документ в 1С
Поступление.Записать(РежимЗаписиДокумента.Проведение);
Как отменить проведение документа в 1С
Поступление.Записать(РежимЗаписиДокумента.ОтменаПроведения);
Как внести изменения в документ по ссылке в 1С
// зачастую у нас есть только ссылка на документ
// и чтобы по ней получить сам объект документа
// для изменения нужно вызывать метод ПолучитьОбъект
// найдём документ под номером А-000000001
// для лаконичности примера воспользуемся не запросом,
// а объектной техникой
СсылкаДокумент = Документы.РеализацияТоваров.НайтиПоНомеру(
"А-000000001",
'20201231' // поиск среди документов 2020 года
);
// нам вернули не сам документ, а ссылку (указатель) на него
// проверим - нашёлся ли вообще документ
Если СсылкаДокумент.Пустая() Тогда
Сообщить("Документ не найден.");
Иначе
// получим сам документ по ссылке
СсылкаДокументОбъект = СсылкаДокумент.ПолучитьОбъект();
// вот его уже можно изменять и записывать
СсылкаДокументОбъект .Клиент = Справочники.Клиенты.НайтиПоНаименованию("Ромашка");
СсылкаДокументОбъект.Записать();
КонецЕсли;
Как получить пустую ссылку типа документ в 1С
ДокументСсылкаПустая = Документы.РеализацияТоваров.ПустаяСсылка();
Если ДокументСсылкаПустая.Пустая() Тогда
Сообщить("Ссылка действительно пустая.");
КонецЕсли;
Как скопировать существующий документ в 1С
// скопируем документ и запишем
// как новый документ от сегодняшнего числа
КопияДокументаОбъект = КакойтоДокументСсылка.Скопировать();
КопияДокументаОбъект.Дата = ТекущаяДата();
КопияДокументаОбъект.Комментарий = "Копия документа " + Строка(КакойтоДокументСсылка);
// запишем и проведём документ
КопияДокументаОбъект.Записать(РежимЗаписиДокумента.Проведение);
Как заблокировать документ перед изменениями в 1С
// выполним блокировку документа
// от изменения другими режимами или пользователями
ДокументОбъект = СсылкаДокумент.ПолучитьОбъект();
Если Не ДокументОбъект .Заблокирован() Тогда
ДокументОбъект .Заблокировать();
// тут идёт какой-то долгий алгоритм
// в результате которого мы меняем
// заблокированный элемент
...
ДокументОбъект.Записать();
// и только потом освобождаем его
// для других режимов и пользователей
ДокументОбъект.Разблокировать();
КонецЕсли;
Как создать новый документ на основании другого объекта в 1С
// создадим документ на основании поступления и заполним
// замечание: в модуле объекта документа РеализацияТоваров дополнительно надо создать обработчик ОбработкаЗаполнения(), в который надо вписать код заполнения табличной части
НоваяРеализацияОбъект = Документы.РеализацияТоваров.СоздатьДокумент();
НоваяРеализацияОбъект.Дата = ТекущаяДата();
НоваяРеализацияОбъект.Комментарий = "Документ введён на основании " + Строка(ДокументСсылкаПоступление1);
НоваяРеализацияОбъект.Заполнить(ДокументСсылкаПоступление1); //тут будет вызвана "ОбработкаЗаполнения"
НоваяРеализацияОбъект.Записать(РежимЗаписиДокумента.Проведение);
Как пометить на удаление документ в 1С
ДокументОбъект.УстановитьПометкуУдаления(Истина);
// метод Записать вызывать не нужно
Как найти и изменить программно движения документа в 1С
&НаСервере
Процедура КакНайтиИИзменитьДвиженияДокументаНаСервере()
// предположим у нас есть ссылка на проведенный
// документ поступления № А-000000001
ПоступлениеСсылка = Документы.ПоступлениеТоваров.НайтиПоНомеру("А-000000001", '20201231');
// мы знаем, что этот документ делает записи по регистру накопления "ТоварыНаСкладах"
// изменим записи по регистру "ТоварыНаСкладах"
ПоступлениеОбъект = ПоступлениеСсылка.ПолучитьОбъект();
// получим набор записей этого документа в регистр ТоварыНаСкладах
НаборЗаписей = ПоступлениеОбъект.Движения.ТоварыНаСкладах;
// прочитаем записи из базы данных
НаборЗаписей.Прочитать();
Для Каждого Запись Из НаборЗаписей Цикл
// выведем старые значения
Сообщить(
Строка(Запись.ВидДвижения) + " " +
Запись.Номенклатура + " " + Запись.Количество
);
// изменим запись, удвоив количество
Запись.Количество = Запись.Количество * 2;
КонецЦикла;
// добавим новую запись
НоваяЗапись = НаборЗаписей.ДобавитьПриход();
НоваяЗапись.Склад = Справочники.Склады.НайтиПоНаименованию("Основной склад");
НоваяЗапись.Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию("Сапоги");
НоваяЗапись.Количество = 3;
НоваяЗапись.Период = ТекущаяДата();
//запишем набор записей
НаборЗаписей.Записать(Истина); // удалим старые движения и запишем вместо них новые
//внимание! после стандартной перезаписи документа наши изменения вновь будут перезаписаны типовым алгоритмом (если он есть в модуле объекта).
КонецПроцедуры
Как прочитать движения документа по регистрам запросом в 1С
&НаСервере
Процедура КакПрочитатьДвиженияДокументаЗапросомНаСервере()
// этот приём используется, если не требуется изменять
// найденные записи
// предположим у нас есть ссылка на проведенный
// документ поступления товаров № А-0000000001
ПоступлениеСсылка =
Документы.ПоступлениеТоваров.НайтиПоНомеру(
"А-0000000001", '20201231');
// прочитаем записи по регистру "ТоварыНаСкладах" запросом
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТоварыНаСкладах.НомерСтроки,
| ТоварыНаСкладах.ВидДвижения,
| ТоварыНаСкладах.Номенклатура,
| ТоварыНаСкладах.Количество
|ИЗ
| РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
|ГДЕ
| ТоварыНаСкладах.Регистратор = &ВыбРегистратор
|
|УПОРЯДОЧИТЬ ПО
| ТоварыНаСкладах.НомерСтроки";
Запрос.УстановитьПараметр("ВыбРегистратор", ПоступлениеСсылка);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка .Следующий() Цикл
Сообщить(
"#" + Выборка.НомерСтроки +
" " + Выборка.ВидДвижения +
" " + Выборка.Номенклатура+
" " + Выборка.Количество
);
КонецЦикла;
КонецПроцедуры
Как изменить проведенный документ, не меняя его в 1С
&НаСервере
Процедура КакИзменитьПроведенныйДокументНеМеняяЕгоДвиженийНаСервере()
// бывает так, что есть проведенный документ
// в уже закрытом периоде и нужно изменить
// некоторое поле документа, но так чтобы
// не поменялись проводки документа
ПоступлениеСсылка =
Документы.ПоступлениеТоваров.НайтиПоНомеру(
"А-0000000001", '20201231');
// Изменим количество в табличной части этого документа
// на 1, но чтобы проводки (движения) остались прежними
Поступление = ПоступлениеСсылка.ПолучитьОбъект();
Для Каждого Строка Из Поступление.Товары Цикл
Строка.Количество = 1;
КонецЦикла;
// если сейчас просто записать документ
// изменятся его проводки, ведь он уже проведён
// но если установить флаг Загрузка
Поступление.ОбменДанными.Загрузка = Истина;
// то можно записать проведенный документ
// без повторного проведения
Поступление.Записать();
КонецПроцедуры
Как найти документ по номеру в 1С
&НаСервереБезКонтекста
Функция ПолучитьДокументПоНомеру(Номер, ДатаИнтервала)
Возврат Документы.РеализацияТоваров.НайтиПоНомеру(Номер, ДатаИнтервала);
КонецФункции
Как открыть форму существующего документа в 1С
&НаКлиенте
Процедура КакОткрытьФормуСуществующегоДокумента(Команда)
СсылкаНаДокумент = Документы.РеализацияТоваров.НайтиПоНомеру("А-000000002", '20201231');
ПараметрыФормы = Новый Структура("Ключ", СсылкаНаДокумент);
ОткрытьФорму(
"Документ.РеализацияТоваров.ФормаОбъекта", // имя формы
ПараметрыФормы // параметры для формы
);
КонецПроцедуры
Как открыть форму выбора документа и отследить её закрытие в 1С
&НаКлиенте
Процедура КакОткрытьФормуВыбораДокумента(Команда)
ОповещениеОЗакрытии = Новый ОписаниеОповещения("ПослеВыбораДокумента",
ЭтотОбъект);
ОткрытьФорму(
"Документ.РеализацияТоваров.ФормаВыбора",,,,,,ОповещениеОЗакрытии
);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораДокумента(Результат, Параметры) Экспорт
Если Результат <> Неопределено Тогда
Сообщить("Был выбран документ " + Результат);
КонецЕсли;
КонецПроцедуры
Как открыть форму списка (журнал) документов с отбором по реквизиту в 1С
&НаКлиенте
Процедура КакОткрытьФормуСпискаДокументовСОтбором(Команда)
// откроем список поступлений, оставив
// только те, что от поставщика ООО "Ромашка"
ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("Поставщик",
НайтиПоставщикаПоИмени("ООО ""Ромашка"""));
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Отбор", ПараметрыОтбора);
ОткрытьФорму(
"Документ.ПоступлениеТоваров.ФормаСписка",
ПараметрыФормы
);
КонецПроцедуры
Как открыть форму только что созданного, но ещё не записанного документа в 1С
&НаКлиенте
Процедура КакОткрытьФормуНовогоНеЗаписанногоДокумента(Команда)
// получаем форму нового документа
ФормаНовогоДокумента = ПолучитьФорму(
"Документ.ПоступлениеТоваров.ФормаОбъекта",,, Истина);
// делаем копию её данных (так как напрямую их менять
// нельзя)
КопияДанныхФормы = ФормаНовогоДокумента.Объект;
// заполняем эти данные на сервере
ЗаполнитьДанныеФормыНаСервере(КопияДанныхФормы);
// копируем заполненные данные в исходную форму
КопироватьДанныеФормы(КопияДанныхФормы,
ФормаНовогоДокумента.Объект);
// показываем форму нового заполненного
// документа пользователю
ФормаНовогоДокумента.Открыть();
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьДанныеФормыНаСервере(ДанныеФормы)
// преобразуем данные формы в документ
Поступление = ДанныеФормыВЗначение(ДанныеФормы,
Тип("ДокументОбъект.ПоступлениеТоваров"));
// заполним только табличную часть
НоваяСтрока = Поступление.Товары.Добавить();
НоваяСтрока.Номенклатура =
Справочники.Номенклатура.НайтиПоНаименованию(
"Сапоги"
);
НоваяСтрока.Количество = 2;
НоваяСтрока.Сумма = 3000;
// преобразуем документа обратно в данные формы
ЗначениеВДанныеФормы(Поступление, ДанныеФормы);
КонецПроцедуры
You have no rights to post comments
Доброго дня, коллеги!
Помните, мы уже разбирали вопрос, где наша внимательная слушательница решила самостоятельно исследовать метаданные конфигурации, в результате чего у нее появились интересные вопросы?
Сегодня у нас похожий случай, когда очередной слушатель, изучая курс Разработка и оптимизация запросов в 1С:Предприятие 8.3, разбираясь в синтаксисе языка запросов 1С, обнаружил занятную деталь.
Вопрос
Если необходимо отобрать тип регистратора для записей регистра, то можно воспользоваться несколькими разными вариантами:
● ГДЕ ТИПЗНАЧЕНИЯ(ТоварныеЗапасы.Регистратор) = ТИП(Документ.РасходТовара) ● ГДЕ ТоварныеЗапасы.Регистратор ССЫЛКА Документ.РасходТовара ● ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.РасходТовара)
А какой из вариантов оптимален с методической точки зрения? Предположительно ВЫРАЗИТЬ исполнится до отбора данных. Так ли это?
Ответ
Можно использовать первые два варианта – оператор ССЫЛКА или функцию ТИПЗНАЧЕНИЯ.
При помощи оператора ВЫРАЗИТЬ можно привести значение только к одному типу:
ВЫРАЗИТЬ Поле КАК Тип
Т.е. сам по себе он не выполняет отбор. Нужно дополнительно в секции ГДЕ установить отбор.
Оператор ССЫЛКА не убирает лишние неявные соединения (это можно проверить при помощи просмотра плана запроса в консоли), а накладывает отбор по типу. А ВЫРАЗИТЬ явно говорит, что поле будет иметь не составной тип, а одну конкретную ссылку, поэтому не будет лишних соединений.
У оператора ССЫЛКА есть особенность.
Пусть используется следующий фрагмент запроса:
&ЦеноваяГруппа ССЫЛКА Справочник.ЦеновыеГруппы
Если в качестве значения параметра ЦеноваяГруппа установить, например, ссылку на справочник «Номенклатура», система выдаст ошибку:
Несовместимые типы “ССЫЛКА”
& ЦеноваяГруппа <<?>>ССЫЛКА Справочник.ЦеновыеГруппы
При работе с реквизитами составного типа тоже может возникать такая же ошибка. Например, документ «РеализацияТоваровУслуг» не входит в составной тип реквизита ДокументОснование документа «Авансовый Отчет». При выполнении запроса будет ошибка:
ВЫБРАТЬ АвансовыйОтчет.ДокументОснование ССЫЛКА Документ.РеализацияТоваровУслуг ИЗ Документ.АвансовыйОтчет КАК АвансовыйОтчет
Причем конструктор запроса даже не будет открываться. ТИПЗНАЧЕНИЯ при этом отработает корректно.
Фирма 1С поясняет это следующим образом:
«Язык запросов выдает эту ошибку, если в типе проверяемого выражения отсутствует ссылка на проверяемую таблицу.»
Вот такую особенность нужно учитывать при разработке запросов.
Кстати, завтра мы вновь вернемся к запросам. Обещаем, будет интересно!
P.S.
Понимать, как работают запросы и уметь их строить — обязательный навык для всех, кто дорабатывает и внедряет 1С.
После курса Вы сможете:
- Строить сложные запросы с несколькими источниками данных
- Уверенно задействовать вложенные запросы и временные таблицы
- Использовать встроенный язык для обработки результатов запроса
- Учитывать особенности соединений и объединений нескольких таблиц.
- Разрабатывать запросы на уровне задач Аттестации 1С:Специалист по платформе.
//вот полный пример где я искал все докменты где есть реквизит валюта и
//потом выбирал из них те, где есть та валюта которую я хочу найти
массивПодходящихДокументов = новый Массив;
Для Каждого Документ Из Документы Цикл
РеквизитыДок = Документ.ПустаяСсылка().Метаданные().Реквизиты;
Если РеквизитыДок.Найти(«Валюта»)<>Неопределено Тогда
массивПодходящихДокументов.Добавить(Документ.ПустаяСсылка());
КонецЕсли;
КонецЦикла;
переменнаяЗначенияПоиска = Справочники.Валюты.НайтиПоНаименованию(«RUB»);;
перемНазваниеРеквизитаПоиска = «Валюта»;
ТекстЗапроса = «ВЫБРАТЬ
| Документ.Ссылка
|ИЗ
| [НаименованиеДокумента] КАК Документ
|ГДЕ
| Документ.[названиеРеквизитаДляПоиска] = &Значение»;
РазделительПакетногоЗапроса = «
|;
|
|////////////////////////////////////////////////////////////////////////////////
|»;
ТекстПакетногоЗапроса = «»;
Для каждого Док из массивПодходящихДокументов Цикл
НаименованиеДок = Док.Метаданные().ПолноеИмя();
Если ТекстПакетногоЗапроса = «» Тогда
ТекстПакетногоЗапроса = СтрЗаменить(ТекстЗапроса, «[НаименованиеДокумента]», Строка(НаименованиеДок));
иначе
ТекстПакетногоЗапроса = ТекстПакетногоЗапроса+РазделительПакетногоЗапроса+СтрЗаменить(ТекстЗапроса, «[НаименованиеДокумента]», Строка(НаименованиеДок));
КонецЕсли;
КонецЦикла;
ТекстПакетногоЗапроса = СтрЗаменить(ТекстПакетногоЗапроса, «[названиеРеквизитаДляПоиска]», Строка(перемНазваниеРеквизитаПоиска));
Запрос = новый Запрос;
Запрос.Текст = ТекстПакетногоЗапроса;
Запрос.УстановитьПараметр(«Значение», переменнаяЗначенияПоиска);
массивРезультат = новый Массив;
массивРезультат = запрос.ВыполнитьПакет();
//получили массив результатов пакетного запроса
//теперь можем перебрать массив и выбрать все найденные документы вот так
Для Каждого Результат из массивРезультат Цикл
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Ссылка);
Сообщить(«Комментарии: «+Выборка.Ссылка.Метаданные().Комментарий);
КонецЦикла;
КонецЦикла;