Как программно создать нового пользователя или скопировать настройки существующего? Часто встречаю вопросы касаемые программного создания и настройки прав пользователей.
В этот статье я приведу примеры для Обычного и Управляемого приложений, которые программно создают пользователя в конфигураторе и в режиме Предприятие (справочник пользователи) и установку Групп пользователей.
В приложении к статье обработки, код которых приведен ниже: Скачать обработки
Обработки были написаны под УТ, но, при необходимости, вы можете их легко доработать под другие конфигурации.
Управляемое приложение: В конфигурациях на управляемом интерфейсе (Такси) изменили подход к ведению пользователей. Если вы добавляете не программно, то добавлять нужно из режима Предприятия - тогда пользователь ИБ у вас сам создатся. И если раньше, в обычном приложении, достаточно будет добавить польз в конфигураторе - и при заходе в Предприятие, этот польз сам создавался в спр Пользователи, то с управляемым приложением такой фокус не прокатит - система не даст зайти под пользователем ИБ, которого нет в справочнике Пользователи.
! В типовых конфигурациях для работы с пользователями активно используется БСП !
В общем модуле Пользователи используется программный интерфейс процедур и функций НовоеОписаниеПользователяИБ , ПрочитатьПользователяИБ , ЗаписатьПользователяИБ иУдалитьПользователяИБ .
Код создания нового пользователя с использованием БСП:
Код 1C v 8.3 &НаСервере
Функция КопированиеВсехНастроек(ПользовательСсылка,ПользовательПриемник)
Пользователь = Обработки.НастройкиПользователей.ИмяПользователяИБ(ПользовательСсылка);
Приемники = Новый Массив;
ТаблицаПользователей = Новый ТаблицаЗначений;
ТаблицаПользователей.Колонки.Добавить("Пользователь");
ТаблицаПользователей = Обработки.НастройкиПользователей.ПользователиДляКопирования(ПользовательСсылка, ТаблицаПользователей,
ТипЗнч(ПользовательСсылка) = Тип("СправочникСсылка.ВнешниеПользователи"));
Для Каждого СтрокаТаблицы Из ТаблицаПользователей Цикл
Приемники.Добавить(ПользовательПриемник);
КонецЦикла;
КопируемыеНастройки = Новый Массив;
КопируемыеНастройки.Добавить("НастройкиОтчетов");
КопируемыеНастройки.Добавить("НастройкиВнешнегоВида");
КопируемыеНастройки.Добавить("ПерсональныеНастройки");
КопируемыеНастройки.Добавить("Избранное");
КопируемыеНастройки.Добавить("НастройкиПечати");
КопируемыеНастройки.Добавить("ПрочиеПользовательскиеНастройки");
НастройкиСкопированы = Обработки.НастройкиПользователей.
КопированиеНастроекПользователей(ПользовательСсылка, Приемники, КопируемыеНастройки);
Возврат НастройкиСкопированы;
КонецФункции
Функция СоздатьНовыйУровеньДоступа(ФИО)
Рез = Справочники.CRM_УровниДоступа.НайтиПоНаименованию(ФИО);
Если Рез = Неопределено ИЛИ Рез = Справочники.CRM_УровниДоступа.ПустаяСсылка() Тогда
НовыйОбъект = Справочники.CRM_УровниДоступа.СоздатьЭлемент();
НовыйОбъект.Наименование = ФИО;
НовыйОбъект.Записать();
возврат НовыйОбъект.Ссылка;
КонецЕсли;
КонецФункции
Процедура ОбновитьДанныеПользователяИБ(ПользовательНастроек, Знач ОтображатьИмя = Истина)
Если ПользовательНастроек = Неопределено Тогда
Возврат;
КонецЕсли;
ПроверкаНаСуществующегоПользователя = ПользователиИнформационнойБазы.НайтиПоИмени(Объект.ФИОСоздаваемогоПользователя);
Если ПроверкаНаСуществующегоПользователя = Неопределено Тогда
Пользователь_Шаблон = ПользователиИнформационнойБазы.НайтиПоИмени(сокрлп(ПользовательНастроек.Наименование));
ОписаниеПользователяИБ = Пользователи.НовоеОписаниеПользователяИБ();
ПользовательИБСуществует = Ложь;
ДоступКИнформационнойБазеРазрешен = Ложь;
// Заполнение начальных значений свойств пользователяИБ.
Если ОбщегоНазначенияПовтИсп.РазделениеВключено() Тогда
ОписаниеПользователяИБ.ПоказыватьВСпискеВыбора = Ложь;
Иначе
ОписаниеПользователяИБ.ПоказыватьВСпискеВыбора =
НЕ Константы.ИспользоватьВнешнихПользователей.Получить();
КонецЕсли;
ОписаниеПользователяИБ.АутентификацияСтандартная = Истина;
ОписаниеПользователяИБ.Роли = Новый Массив;
ПрочитанныеСвойства = Неопределено;
Если Пользователи.ПрочитатьПользователяИБ(
ПользовательНастроек.ИдентификаторПользователяИБ,ПрочитанныеСвойства
) Тогда
// Установка связи пользователем ИБ.
//ДоступКИнформационнойБазеРазрешен = Истина;
// Копирование свойств и ролей пользователяИБ.
ЗаполнитьЗначенияСвойств(
ОписаниеПользователяИБ,
ПрочитанныеСвойства,
"АутентификацияOpenID,
|АутентификацияСтандартная,
|ЗапрещеноИзменятьПароль,
|ПоказыватьВСпискеВыбора,
|АутентификацияОС,
|РежимЗапуска,
|Язык,
|Роли");
КонецЕсли;
ОписаниеПользователяИБ.Вставить("Действие", "Записать");
ОписаниеПользователяИБ.Вставить("Имя", Объект.ФИОСоздаваемогоПользователя);
НовыйПользователь = Справочники.Пользователи.СоздатьЭлемент();
НовыйПользователь.Наименование = Объект.ФИОСоздаваемогоПользователя;
НовыйПользователь.ТекущееПодразделение = ПользовательНастроек.ТекущееПодразделение;
НовыйПользователь.CRM_УровеньДоступа = СоздатьНовыйУровеньДоступа(Объект.ФИОСоздаваемогоПользователя);
НовыйПользователь.Недействителен = ложь;
НовыйПользователь.ДополнительныеСвойства.Вставить(
"ОписаниеПользователяИБ", ОписаниеПользователяИБ);
НовыйПользователь.Записать();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ГруппыПользователейПользователиГруппы.Ссылка
|ИЗ
| Справочник.ГруппыПользователей.Состав КАК ГруппыПользователейПользователиГруппы
|ГДЕ
| ГруппыПользователейПользователиГруппы.Пользователь =Пользователь
|
|СГРУППИРОВАТЬ ПО
| ГруппыПользователейПользователиГруппы.Ссылка";
Запрос.УстановитьПараметр("Пользователь", ПользовательНастроек);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
объ = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
НоваяСтрока = объ.Состав.Добавить();
НоваяСтрока.Пользователь = НовыйПользователь.Ссылка;
объ.Записать();
КонецЦикла;
Запрос.Текст =
"ВЫБРАТЬ
| ГруппыДоступаПользователи.Ссылка
|ИЗ
| Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
|ГДЕ
| ГруппыДоступаПользователи.Пользователь =Пользователь
|
|СГРУППИРОВАТЬ ПО
| ГруппыДоступаПользователи.Ссылка";
Запрос.УстановитьПараметр("Пользователь", ПользовательНастроек);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
объ = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
НоваяСтрока = объ.Пользователи.Добавить();
НоваяСтрока.Пользователь = НовыйПользователь.Ссылка;
объ.Записать();
КонецЦикла;
КопированиеВсехНастроек(ПользовательНастроек,НовыйПользователь.Ссылка);
Иначе
сообщить("Указанное ФИО Пользователя уже используется !!! ");
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура СоздатьПользователя(Команда)
СоздатьПользователяНаСервере();
КонецПроцедуры
&НаСервере
Процедура СоздатьПользователяНаСервере()
Если НЕ ЗначениеЗаполнено(Объект.ШаблонПользователяДляСозданияНового) Тогда
Возврат;
КонецЕсли;
// настройки устанавливаются на форму
ОбновитьДанныеПользователяИБ(Объект.ШаблонПользователяДляСозданияНового, Ложь);
КонецПроцедуры
&НаСервере
Процедура СкопироватьНастройкиНаСервере(ИзменяемыйПользователь,ШаблонПользователяДляКопирования)
//Копируем роли пользователя
тИзменяемыйПользователь = ПользователиИнформационнойБазы.НайтиПоИмени(сокрлп(ИзменяемыйПользователь.Наименование));
тШаблонПользователяДляКопирования = ПользователиИнформационнойБазы.НайтиПоИмени(сокрлп(ШаблонПользователяДляКопирования.Наименование));
//Очищаем роли
тИзменяемыйПользователь.Роли.Очистить();
// Копируем
СписокДоступныхРолейПользователяИБ = Новый СписокЗначений;
Для Каждого мРоль Из Метаданные.Роли Цикл
СтрокаСписокаДоступныхРолей = СписокДоступныхРолейПользователяИБ.Добавить();
СтрокаСписокаДоступныхРолей.Представление = мРоль.Представление();
СтрокаСписокаДоступныхРолей.Значение = мРоль;
КонецЦикла;
Для Каждого СтрокаСпискаДоступныхРолей Из СписокДоступныхРолейПользователяИБ Цикл
Если тШаблонПользователяДляКопирования.Роли.Содержит(СтрокаСпискаДоступныхРолей.Значение) Тогда
тИзменяемыйПользователь.Роли.Добавить(СтрокаСпискаДоступныхРолей.Значение);
КонецЕсли;
КонецЦикла;
тИзменяемыйПользователь.Записать();
//Копируем настройки БСП
КопированиеВсехНастроек(ШаблонПользователяДляКопирования,ИзменяемыйПользователь);
КонецПроцедуры
&НаКлиенте
Процедура СкопироватьНастройки(Команда)
СкопироватьНастройкиНаСервере(Объект.ИзменяемыйПользователь, Объект.ШаблонПользователяДляКопирования);
КонецПроцедуры
Обычное приложение: В обычном все проще:
Код 1C v 8.х Процедура КнопкаВыполнитьНажатие(Кнопка)
Если НЕ ЗначениеЗаполнено(ШаблонПользователяДляСозданияНового) Тогда
Возврат;
КонецЕсли;
// настройки устанавливаются на форму
ОбновитьДанныеПользователяИБ(ШаблонПользователяДляСозданияНового, Ложь);
КонецПроцедуры
Процедура ОбновитьДанныеПользователяИБ(ПользовательНастроек, Знач ОтображатьИмя = Истина)
Если ПользовательНастроек = Неопределено Тогда
Возврат;
КонецЕсли;
ПроверкаНаСуществующегоПользователя = ПользователиИнформационнойБазы.НайтиПоИмени(ФИОСоздаваемогоПользователя);
Если ПроверкаНаСуществующегоПользователя = Неопределено Тогда
Пользователь_Шаблон = ПользователиИнформационнойБазы.НайтиПоИмени(сокрлп(ПользовательНастроек.Код));
ПользовательИБ = ПользователиИнформационнойБазы.СоздатьПользователя();
ПользовательИБ.Имя = ФИОСоздаваемогоПользователя;
ПользовательИБ.АутентификацияСтандартная = Истина;
ПользовательИБ.Пароль = ПарольСоздаваемогоПользователя;
ПользовательИБ.ПолноеИмя = ФИОСоздаваемогоПользователя;
ПользовательИБ.ПоказыватьВСпискеВыбора = Истина;
ПользовательИБ.ОсновнойИнтерфейс = Пользователь_Шаблон.ОсновнойИнтерфейс;
ПользовательИБ.Язык = Пользователь_Шаблон.Язык;
СписокДоступныхРолейПользователяИБ = Новый СписокЗначений;
Для Каждого мРоль Из Метаданные.Роли Цикл
СтрокаСписокаДоступныхРолей = СписокДоступныхРолейПользователяИБ.Добавить();
СтрокаСписокаДоступныхРолей.Представление = мРоль.Представление();
СтрокаСписокаДоступныхРолей.Значение = мРоль;
КонецЦикла;
Для Каждого СтрокаСпискаДоступныхРолей Из СписокДоступныхРолейПользователяИБ Цикл
Если Пользователь_Шаблон.Роли.Содержит(СтрокаСпискаДоступныхРолей.Значение) Тогда
ПользовательИБ.Роли.Добавить(СтрокаСпискаДоступныхРолей.Значение);
КонецЕсли;
КонецЦикла;
ПользовательИБ.Записать();
НовыйПользователь = Справочники.Пользователи.СоздатьЭлемент();
//НовыйПользователь.ИдентификаторПользователяИБ = ПользовательИБ.УникальныйИдентификатор;
НовыйПользователь.Код = ФИОСоздаваемогоПользователя;
НовыйПользователь.Наименование = ФИОСоздаваемогоПользователя;
НовыйПользователь.Родитель = ПользовательНастроек.Родитель;
НовыйПользователь.Подразделение = ПользовательНастроек.Подразделение;
НовыйПользователь.Категория = ПользовательНастроек.Категория;
НовыйПользователь.Руководитель = ПользовательНастроек.Руководитель;
НовыйПользователь.Действует = ПользовательНастроек.Действует;
НовыйПользователь.Записать();
НаборПользователя = РегистрыСведений.НастройкиПользователей.СоздатьНаборЗаписей();
НаборПользователя.Отбор.Пользователь.Установить(ПользовательНастроек);
НаборПользователя.Прочитать();
НаборНовогоПользователя = РегистрыСведений.НастройкиПользователей.СоздатьНаборЗаписей();
НаборНовогоПользователя.Отбор.Пользователь.Установить(НовыйПользователь.Ссылка);
Для Каждого СтрокаНастроек из НаборПользователя Цикл
НоваяСтрокаНастроек = НаборНовогоПользователя.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрокаНастроек,СтрокаНастроек);
НоваяСтрокаНастроек.Пользователь = НовыйПользователь.Ссылка;
Если Найти(СтрокаНастроек.Настройка.Наименование,"Основной ответственный") Тогда
НоваяСтрокаНастроек.Значение = НовыйПользователь.Ссылка;
КонецЕсли;
КонецЦикла;
Если НаборНовогоПользователя.Количество()>0 Тогда
НаборНовогоПользователя.Записать();
КонецЕсли;
сообщить("Создан пользователь "+ФИОСоздаваемогоПользователя);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ГруппыПользователейПользователиГруппы.Ссылка
|ИЗ
| Справочник.ГруппыПользователей.ПользователиГруппы КАК ГруппыПользователейПользователиГруппы
|ГДЕ
| ГруппыПользователейПользователиГруппы.Пользователь =Пользователь
|
|СГРУППИРОВАТЬ ПО
| ГруппыПользователейПользователиГруппы.Ссылка";
Запрос.УстановитьПараметр("Пользователь", ПользовательНастроек);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
объ = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
НоваяСтрока = объ.ПользователиГруппы.Добавить();
НоваяСтрока.Пользователь = НовыйПользователь.Ссылка;
объ.Записать();
КонецЦикла;
Иначе
сообщить("Указанное ФИО Пользователя уже используется !!! ");
КонецЕсли;
КонецПроцедуры
еще пример:
Код 1C v 8.х Функция ДобавитьПользователя(ИмяПользователя, ДоменноеИмя, ПользовательАктивен, АутентификацияОС, Авторизация1СПредприятия, МассивРолей) Экспорт
// Попробуем найти сотрудника
Пользователь = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователя);
// Теперь попробум найти сотрудника по пользователю ос
Если Пользователь = Неопределено Тогда
Для Каждого ТекущийПользователь Из ПользователиИнформационнойБазы.ПолучитьПользователей() Цикл
Если ТекущийПользователь.ПользовательОС = ДоменноеИмя Тогда
Пользователь = ТекущийПользователь;
Прервать;
Конецесли;
КонецЦикла;
КонецЕсли;
//
// Если мы не нашли сотрудника, то создадим его
Если Пользователь = Неопределено Тогда
Пользователь = ПользователиИнформационнойБазы.СоздатьПользователя();
КонецЕсли;
//
// Записываем свойства
Пользователь.АутентификацияОС = АутентификацияОС;
Пользователь.АутентификацияСтандартная = Авторизация1СПредприятия;
Пользователь.ЗапрещеноИзменятьПароль = Истина;
Пользователь.Имя = ИмяПользователя;
Пользователь.ПолноеИмя = ИмяПользователя;
Пользователь.ПоказыватьВСпискеВыбора = Ложь;
Пользователь.ПользовательОС = ДоменноеИмя;
// Сначала очистим все текущие роли
Пользователь.Роли.Очистить();
// Теперь найдем переданный массив ролей в справочнике профилей
// и добавим все роли указанные в профиле. Все очень сложно, да
МассивИменРолей = Новый Массив();
Для Каждого Роль Из МассивРолей.Role Цикл
МассивИменРолей.Добавить(Роль);
КонецЦикла;
ТекстЗапроса = "ВЫБРАТЬ
| ПрофилиГруппДоступаРоли.Роль.Имя КАК Имя
|ИЗ
| Справочник.ПрофилиГруппДоступа.Роли КАК ПрофилиГруппДоступаРоли
|ГДЕ
| ПрофилиГруппДоступаРоли.Ссылка.Наименование В(&МассивИменРолей)";
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("МассивИменРолей", МассивИменРолей);
Результат = Запрос.Выполнить().Выгрузить();
Для Каждого Роль Из Результат Цикл
НайденнаяРоль = Метаданные.Роли.Найти(Роль.Имя);
Если НайденнаяРоль <> Неопределено Тогда
Пользователь.Роли.Добавить(НайденнаяРоль);
КонецЕсли;
КонецЦикла;
// Записываем!
Пользователь.Записать();
// Теперь посмотрим нужно ли деактивировать пользователя
Если Не ПользовательАктивен Тогда
ДективироватьПользователя(Пользователь);
КонецЕсли;
// Запишем еще и справочник пользователя
ЗаполнитьСправочникПользователя(Пользователь);
Возврат Истина;
КонецФункции
// Процедура заполняет помимо прочего справочник пользователя
Процедура ЗаполнитьСправочникПользователя(ПользовательИБ) Экспорт
ТекстЗапроса = "ВЫБРАТЬ
| ИСТИНА КАК ЕстьПользователь,
| Пользователи.Ссылка КАК Пользователь
|ИЗ
| Справочник.Пользователи КАК Пользователи
|ГДЕ
| Пользователи.ИдентификаторПользователяИБ =ИдентификаторПользователяИБ
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ЛОЖЬ,
| NULL";
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("ИдентификаторПользователяИБ", ПользовательИБ.УникальныйИдентификатор);
Результат = Запрос.Выполнить().Выгрузить()[0];
ОписаниеПользователя = Пользователи.НовоеОписаниеПользователяИБ();
Если Результат.ЕстьПользователь Тогда
ПользовательОбъект = Результат.Пользователь.ПолучитьОбъект();
Иначе
ПользовательОбъект = Справочники.Пользователи.СоздатьЭлемент();
ПользовательОбъект.ИдентификаторПользователяИБ = ПользовательИБ.УникальныйИдентификатор;
ПользовательОбъект.Наименование = ПользовательИБ.Имя;
ОписаниеПользователя.Вставить("Действие", "Записать");
ПользовательОбъект.ДополнительныеСвойства.Вставить("ОписаниеПользователяИБ", ОписаниеПользователя);
КонецЕсли;
ЗаполнитьЗначенияСвойств(ОписаниеПользователя, ПользовательИБ);
Для Каждого Элемент Из ОписаниеПользователя Цикл
ПользовательОбъект.ДополнительныеСвойства.Вставить(Элемент.Ключ, Элемент.Значение);
КонецЦикла;
ПользовательОбъект.ДополнительныеСвойства.Удалить("Роли");
ПользовательОбъект.Записать();
КонецПроцедуры
Категория:
Пользователь, роль доступа, интерфейс Управление регистрацией документа в последовательности документов Для управления регистрацией документа в последовательности документов служит набор записей регистрации в последовательности документов.
У документа есть свойство ПринадлежностьПоследовательностям. Значением свойства является коллекция наборов записей регистрации в последовательности документов. Для каждой последовательности, в которой участвует документ, существует свой собственный экземпляр набора записей. Если у документа стоит режим автоматического заполнения последовательностей, то перед записью документа наборы записей регистрации будут автоматически заполнены. Для последовательностей без измерений набор записей будет содержать только одну запись. Для последовательностей с измерениями число записей зависит от содержания документа и настройки соответствия измерений последовательности реквизитам документа.
Набор записей автоматически заполняется до записи документа и записывается после записи документа в одной транзакции с ним. Это позволяет в обработчиках событий документа ПередЗаписью() и ПриЗаписи() переопределить набор записей регистрации. Так, например, если документ входит в последовательность Последовательность1 и у документа стоит признак автоматического заполнения последовательности, то для того что бы отменить его регистрацию в последовательности в зависимости от значения реквизита документа достаточно в модуль документа вставить обработчик события ПередЗаписью() следующего содержания:
Код 1C v 8.х Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Если Не Регистрировать Тогда
ПринадлежностьПоследовательностям.Последовательность1.Очистить();
КонецЕсли;
КонецПроцедуры
В этом случае если реквизит Регистрировать имеет значение "Ложь", то документ не будет зарегистрирован в последовательности Последовательность1. Кроме отмены регистрации документа в последовательности, доступна возможность написания собственного алгоритма регистрации документа в последовательности. Для этого надо очистить набор записей регистрации и заполнить его новыми записями.
Код 1C v 8.х Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
ПринадлежностьПоследовательностям.Последовательность1.Очистить();
Если ВидРегистрации = 1 Тогда
ЗП = ПринадлежностьПоследовательностям.Последовательность1.Добавить();
ЗП.Измерение = Реквизит1;
ИначеЕсли ВидРегистрации = 2 Тогда
ПринадлежностьПоследовательностям.Последовательность1.Добавить();
ЗП.Измерение = Реквизит2;
КонецЕсли;
КонецПроцедуры
Пример
Код 1C v 8.х // Зарегистрируем в последовательности УУ
Если ОтражатьВУправленческомУчете Тогда
ЗаписьРегистрации = ПринадлежностьПоследовательностям.ПартионныйУчет.Добавить();
ЗаписьРегистрации.Период = Дата;
КонецЕсли;
Процедура ПоследовательностьВзаиморачеты(ДокумСсылка) Экспорт
ДокументМоментВремени = Новый МоментВремени(ДокумСсылка.дата, ДокумСсылка);
НаборЗаписей = Последовательности.Взаиморасчеты.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(ДокумСсылка);
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Регистратор = ДокумСсылка;
НоваяЗапись.Период = ДокумСсылка.Дата;
НаборЗаписей.Записать();
//Установим границу последовательности на документ
Последовательности.Взаиморасчеты.УстановитьГраницу(ДокументМоментВремени);
КонецПроцедуры
Функция ПолучитьГраницуПоследовательности(Организация = Неопределено) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПартионныйУчетГраницы.МоментВремени
|ИЗ
| Последовательность.ПартионныйУчет.Границы КАК ПартионныйУчетГраницы
|";
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Возврат Выборка.МоментВремени;
Иначе
Возврат Новый МоментВремени('00010101');
КонецЕсли;
КонецФункции
Процедура ОбновитьСписокПоследовательностей()
Для каждого Последовательность Из Обр.СписокПоследовательностей Цикл
ИмяПоследовательности = Последовательность.ИмяПоследовательности;
ГраницаПоследовательности = Последовательности[ИмяПоследовательности].ПолучитьГраницу();
ДатаГраницы = ГраницаПоследовательности.Дата;
Последовательность.Актуальность = "" + ДатаГраницы + " " + ГраницаПоследовательности.Ссылка;
Последовательность.ДатаГраницы = ДатаГраницы;
КонецЦикла;
КонецПроцедуры
// Процедура выполняет поиск и исправление ошибок в последовательности.
//
Процедура КорректировкаРегистрацииВПоследовательности()
Для Каждого ТекПоследовательность Из Метаданные.Последовательности Цикл
ТекстЕстьДвижения = "
| ВЫБОР
| КОГДА СписанныеТоварыСрезПоследних.Регистратор ЕСТЬ NULL";
Для Каждого ДвиженияВлияющиеНаПоследовательность Из ТекПоследовательность.Движения Цикл
ТекстЕстьДвижения = ТекстЕстьДвижения + "
| И РегистрНакопления" + ДвиженияВлияющиеНаПоследовательность.Имя + ".Регистратор ЕСТЬ NULL";
КонецЦикла;
ТекстЕстьДвижения = ТекстЕстьДвижения + "
| ТОГДА ЛОЖЬ
| ИНАЧЕ ИСТИНА
| КОНЕЦ";
ТекстЗапроса = "ВЫБРАТЬ
| Последовательность.Регистратор КАК Регистратор,
| Последовательность.Регистратор.Проведен КАК Проведен,
| Последовательность.Регистратор.Дата КАК Дата,
| Последовательность.Период КАК Период,
|" + ТекстЕстьДвижения + " КАК ЕстьДвижения
|ИЗ
| Последовательность." + ТекПоследовательность.Имя + " КАК Последовательность
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СписанныеТовары КАК СписанныеТоварыСрезПоследних
| ПО Последовательность.Регистратор = СписанныеТоварыСрезПоследних.Регистратор
| И СписанныеТоварыСрезПоследних.НомерСтроки = 1";
Для Каждого ДвиженияВлияющиеНаПоследовательность Из ТекПоследовательность.Движения Цикл
ТекстЗапроса = ТекстЗапроса + "
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления." +ДвиженияВлияющиеНаПоследовательность.Имя + ".Обороты(, , Регистратор, ) КАК РегистрНакопления" + ДвиженияВлияющиеНаПоследовательность.Имя + "
| ПО Последовательность.Регистратор = РегистрНакопления" + ДвиженияВлияющиеНаПоследовательность.Имя + ".Регистратор";
КонецЦикла;
ТекстЗапроса = ТекстЗапроса + "
|ГДЕ
| НЕ (Последовательность.Регистратор.Проведен
| И (Последовательность.Регистратор ССЫЛКА Документ.КорректировкаСтоимостиСписанияТоваров
| ИЛИ Последовательность.Регистратор.Дата = Последовательность.Период)
| И " + ТекстЕстьДвижения + ")
|";
Запрос = Новый Запрос(ТекстЗапроса);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если Не Выборка.Проведен Тогда
НаборЗаписей = Последовательности[ТекПоследовательность.Имя].СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(Выборка.Регистратор);
НаборЗаписей.Записать();
ИначеЕсли (Выборка.Дата <> Выборка.Период)
И (ТипЗнч(Выборка.Регистратор) <> Тип("ДокументСсылка.КорректировкаСтоимостиСписанияТоваров")) Тогда
НаборЗаписей = Последовательности[ТекПоследовательность.Имя].СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(Выборка.Регистратор);
НаборЗаписей.Прочитать();
Для Каждого СтрокаНабора Из НаборЗаписей Цикл
СтрокаНабора.Период = Выборка.Дата;
КонецЦикла;
НаборЗаписей.Записать();
КонецЕсли;
Если Не Выборка.ЕстьДвижения Тогда
НаборЗаписей = Последовательности[ТекПоследовательность.Имя].СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(Выборка.Регистратор);
НаборЗаписей.Записать();
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура УдалитьРегистрациюДокументаВПоследовательностях(ДокументОбъект, ПроверятьДвижения = Ложь)Экспорт
// получение списка последовательностей в которых зарегистрирован документ
Если ПроверятьДвижения Тогда
ТаблицаРегистраций = ОпределитьНаличиеРегистрацииДокументаВПоследовательности(ДокументОбъект);
КонецЕсли;
КоллекцияПоследовательностей = ДокументОбъект.ПринадлежностьПоследовательностям;
Для Каждого НаборЗаписейРегистрацииВПоследовательности ИЗ КоллекцияПоследовательностей Цикл
Если (НаборЗаписейРегистрацииВПоследовательности.Количество() > 0)
ИЛИ (ПроверятьДвижения И (НЕ ТаблицаРегистраций.Найти(НаборЗаписейРегистрацииВПоследовательности.Метаданные().Имя,"Имя") = Неопределено)) Тогда
НаборЗаписейРегистрацииВПоследовательности.Очистить();
КонецЕсли;
КонецЦикла;
КонецПроцедуры//УдалитьРегистрациюДокументаВПоследовательностях
Функция ОпределитьНаличиеРегистрацииДокументаВПоследовательности(ДокументОбъект) Экспорт
ТекстЗапроса = "";
Для Каждого Последовательность ИЗ ДокументОбъект.ПринадлежностьПоследовательностям Цикл
// в запросе получаем имена последовательностей, в которых документ зарегистрирован
ТекстЗапроса = ТекстЗапроса + "
|" + ?(ТекстЗапроса = "", "", "ОБЪЕДИНИТЬ ВСЕ ") + "
|ВЫБРАТЬ """ + Последовательность.Метаданные().Имя
+ """ КАК Имя ИЗ " + Последовательность.Метаданные().ПолноеИмя()
+ " ГДЕ Регистратор =Регистратор";
КонецЦикла;
Если ТекстЗапроса = "" Тогда
Возврат Новый ТаблицаЗначений();
Иначе
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("Регистратор", ДокументОбъект.Ссылка);
ТаблицаЗапроса = Запрос.Выполнить().Выгрузить();
Возврат ТаблицаЗапроса;
КонецЕсли;
КонецФункции
Категория:
Документы Объектная модель схемы запроса Периодически во встроенном языке возникает необходимость изменения текста запроса в зависимости от разных алгоритмических условий. Раньше подобная задача решалась путём непосредственного формирования нужного текста запроса в виде строки. А это не всегда удобно и зачастую очень громоздко.
Теперь во встроенном языке мы реализовали объектную модель схемы запроса. Вы можете создать пустую схему запроса конструктором и загрузить в неё имеющийся текст запроса. После этого отдельные элементы текста запроса будут доступны вам как свойства объектной модели.
На рисунке ниже стрелки показывают, в каких объектах встроенного языка будут доступны те или иные элементы простого запроса, загруженного в схему:
Редактирование текста запроса с помощью объектной модели позволяет вам проще и понятнее модифицировать имеющиеся запросы. Или даже создавать их во встроенном языке «с нуля». А затем просто получать готовый текст запроса из схемы методом ПолучитьТекстЗапроса() .
Пример использования Схемы запроса Код 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");
Продолжить;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Категория:
Запросы Получение уникального идентификатора ссылки в СКД Как известно, с помощью языка запросов 1С получить уникальный идентификатор объекта ссылочного типа на данный момент нельзя. Но используя возможность СКД обращаться к внешним функциям можно получить строковое представление уникального идентификатора ссылки. Для этого необходимо использовать глобальную функцию XMLСтрока в вычисляемых полях в макете схемы компоновки.
Далее проведем эксперимент по быстродействию получения результата через запрос с последующей обработкой выборки и вариантов с использованием СКД.
Рассмотрим два случая - вывод в табличный документ и формирование текстового документа.
Так же в случае с СКД мы можем создать схему компоновки программно или использовать готовую. Результат работы СКД так же можно обойти в цикле, либо вывести в таблицу значений с последующей обработкой. Для экспериментов будет использоваться платформа 8.3, конфигурация УТ11 (файловая), справочник "КлассификаторБанковРФ", более 4000 элементов.
Схему компоновки и макет можно посмотреть, скачав обработку (ссылка в конце).
Код 1C v 8.2 УП &НаКлиентеНаСервереБезКонтекста
Функция ПолучитьТекстЗапроса()
Возврат "ВЫБРАТЬ
| КлассификаторБанковРФ.Ссылка,
| КлассификаторБанковРФ.Наименование
|ИЗ
| Справочник.КлассификаторБанковРФ КАК КлассификаторБанковРФ";
КонецФункции // ПолучитьТекстЗапроса()
&НаСервере
Функция ПолучитьСхемуОбработки()
Возврат РеквизитФормыВЗначение("Отчет").ПолучитьМакет("Макет");
КонецФункции
&НаСервереБезКонтекста
Функция ПолучитьСхемуКомпоновки()
Схема = Новый СхемаКомпоновкиДанных;
ИсточникДанных = Схема.ИсточникиДанных.Добавить();
ИсточникДанных.Имя = "Источник";
ИсточникДанных.ТипИсточникаДанных = "Local";
НаборДанных = Схема.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
НаборДанных.Имя = "НаборДанных";
НаборДанных.ИсточникДанных = "Источник";
НаборДанных.Запрос = ПолучитьТекстЗапроса();
НаборСсылка = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
НаборСсылка.Поле = "Ссылка";
НаборСсылка.ПутьКДанным = "Ссылка";
НаборНаименование= НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
НаборНаименование.Поле = "Наименование";
НаборНаименование.ПутьКДанным = "Наименование";
ПолеИД = Схема.ВычисляемыеПоля.Добавить();
ПолеИД.Выражение = "XMLСтрока(Ссылка)";
ПолеИД.Заголовок = "ИД";
ПолеИД.ПутьКДанным = "ИД";
СтрокаТЗ = Схема.НастройкиПоУмолчанию.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
СтрокаТЗ.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
ЭлементыВыбора = Схема.НастройкиПоУмолчанию.Выбор.Элементы;
ПолеСсылка = ЭлементыВыбора.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
ПолеСсылка.Поле = Новый ПолеКомпоновкиДанных("Ссылка");
ПолеНаименование = ЭлементыВыбора.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
ПолеНаименование.Поле = Новый ПолеКомпоновкиДанных("Наименование");
ПолеИД = ЭлементыВыбора.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
ПолеИД.Поле = Новый ПолеКомпоновкиДанных("ИД");
Возврат Схема;
КонецФункции
&НаСервереБезКонтекста
Функция ЗаполнитьПоКомпоновкеПрямойОбход(Схема)
Док = Новый ТекстовыйДокумент;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Макет = КомпоновщикМакета.Выполнить(Схема, Схема.НастройкиПоУмолчанию,,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(Макет,,, Истина);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(Новый ТаблицаЗначений);
ПроцессорВывода.НачатьВывод();
Пока Истина Цикл
ЭлементКомпоновки = ПроцессорКомпоновки.Следующий();
Если ЭлементКомпоновки = Неопределено Тогда
Прервать;
КонецЕсли;
ПроцессорВывода.ВывестиЭлемент(ЭлементКомпоновки);
Если ЭлементКомпоновки.Макет = "Макет2" И ЭлементКомпоновки.ТипЭлемента = ТипЭлементаРезультатаКомпоновкиДанных.НачалоИКонец Тогда
Док.ДобавитьСтроку(ЭлементКомпоновки.ЗначенияПараметров.П2.Значение + ";" + ЭлементКомпоновки.ЗначенияПараметров.П3.Значение);
КонецЕсли;
КонецЦикла;
ТЗ = ПроцессорВывода.ЗакончитьВывод();
Возврат Док;
КонецФункции // ЗаполнитьПоКомпоновкеПрямойОбход()
&НаСервере
Функция ЗаполнитьОбходТЗ(ИспользоватьСхемуОбработки)
Если ИспользоватьСхемуОбработки Тогда
Схема = ПолучитьСхемуОбработки();
Иначе
Схема = ПолучитьСхемуКомпоновки();
КонецЕсли;
Возврат ЗаполнитьПоКомпоновкеОбходТЗ(Схема);
//Возврат ЗаполнитьПоКомпоновкеОбходТЗ(?(ИспользоватьСхемуОбработки, ПолучитьСхемуОбработки(), ПолучитьСхемуКомпоновки()));
КонецФункции // ЗаполнитьОбходТЗ()
&НаСервере
Функция ЗаполнитьПрямойОбход(ИспользоватьСхемуОбработки)
Если ИспользоватьСхемуОбработки Тогда
Схема = ПолучитьСхемуОбработки();
Иначе
Схема = ПолучитьСхемуКомпоновки();
КонецЕсли;
Возврат ЗаполнитьПоКомпоновкеПрямойОбход(Схема);
//Возврат ЗаполнитьПоКомпоновкеПрямойОбход(?(ИспользоватьСхемуОбработки, ПолучитьСхемуОбработки(), ПолучитьСхемуКомпоновки()));
КонецФункции // ЗаполнитьОбходТЗ()
&НаСервереБезКонтекста
Функция ЗаполнитьПоКомпоновкеОбходТЗ(Схема)
Док = Новый ТекстовыйДокумент;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Макет = КомпоновщикМакета.Выполнить(Схема, Схема.НастройкиПоУмолчанию,,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(Макет,,, Истина);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(Новый ТаблицаЗначений);
ТЗ = ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Для Каждого СтрокаТЗ Из ТЗ Цикл
Док.ДобавитьСтроку(СтрокаТЗ.Наименование + ";" + СтрокаТЗ.ИД);
КонецЦикла;
Возврат Док;
КонецФункции // ЗаполнитьПоКомпоновкеОбходТЗ()
&НаСервереБезКонтекста
Функция ЗаполнитьПоЗапросу()
Док = Новый ТекстовыйДокумент;
Запрос = Новый Запрос(ПолучитьТекстЗапроса());
Результат = Запрос.Выполнить().Выбрать();
Пока Результат.Следующий() Цикл
Док.ДобавитьСтроку(Результат.Наименование + ";" + XMLСтрока(Результат.Ссылка));
КонецЦикла;
Возврат Док;
КонецФункции // ЗаполнитьПоЗапросу()
&НаСервере
Процедура ЗаполнитьТабДокСхема(ИспользоватьСхемуОбработки)
Если ИспользоватьСхемуОбработки Тогда
Схема = ПолучитьСхемуОбработки();
ТабДок = ТабДок1;
Иначе
Схема = ПолучитьСхемуКомпоновки();
ТабДок = ТабДок2;
КонецЕсли;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Макет = КомпоновщикМакета.Выполнить(Схема, Схема.НастройкиПоУмолчанию);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(Макет,,, Истина);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабДок);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры // ЗаполнитьТабДокСхема()
&НаСервере
Процедура ЗаполнитьТабДокЗапрос()
Макет = РеквизитФормыВЗначение("Отчет").ПолучитьМакет("Отчет");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
Запрос = Новый Запрос(ПолучитьТекстЗапроса());
Результат = Запрос.Выполнить().Выбрать();
Пока Результат.Следующий() Цикл
ОбластьСтрока.Параметры.Заполнить(Результат);
ОбластьСтрока.Параметры.ИД = XMLСтрока(Результат.Ссылка);
ТабДок3.Вывести(ОбластьСтрока);
КонецЦикла;
КонецПроцедуры
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ЗаполнитьТабДокСхема(Истина);
ЗаполнитьТабДокСхема(Ложь);
ЗаполнитьТабДокЗапрос();
Т1 = ЗаполнитьПоЗапросу();
Т2 = ЗаполнитьОбходТЗ(Ложь);
Т3 = ЗаполнитьОбходТЗ(Истина);
Т4 = ЗаполнитьПрямойОбход(Ложь);
Т5 = ЗаполнитьПрямойОбход(Истина);
КонецПроцедуры
По результатам замера производительности видно, что вывод результата в табличный документ происходит быстрее при использовании СКД, причем вариант с программным созданием схемы отрабатывает несколько быстрее.
В тоже время вывод результатов в текстовый документ отрабатывает быстрее для запроса.
Программное создание схемы компоновки отработало быстрее, чем получение макета схемы.
Источник
Категория:
Схема Компоновки Данных COM-подключение к базе 7.7 из 8.2 1С Если код выполняется на стороне клиента, то необходимо наличие базы 7.7 на локальной машине.
Пример (На форме объекта присутствует реквизит Таблица(ТаблицаЗначений)):
Код 1C v 8.2 УП &НаКлиенте
Процедура Загрузки()
ПутьКБазе="D:\ВашаБаза\1с77\";
Пользователь="stvbliz";//пользователь базы 7.7
Пароль="вашпароль";
МонопольныйРежимOLE = ""; // " /m";
ЗапускБезЗаставки = 1;
База = Новый COMОбъект("V1CEnterprise.Application");
СтрокаПодключения = "/D"""+СокрЛП(ПутьКБазе)+""" /N"""+СокрЛП(Пользователь)+""" /P"""+СокрЛП(Пароль)+"""";
РезультатПодключения=База.Initialize(База.RMTrade,СтрокаПодключения,?(ЗапускБезЗаставки = 1,"NO_SPLASH_SHOW",""));
Если НЕ РезультатПодключения Тогда
Сообщить("Не удалось произвести подключение к информационной базе");
КонецЕсли;
Таблица.Очистить();
Док = База.CreateObject("Документ.ЗаявкаПокупателя");
Док.ВыбратьДокументы(НачалоНедели(Дата),КонецНедели(Дата));
Пока Док.ПолучитьДокумент() = 1 Цикл
ОбработкаПрерыванияПользователя();
Если Док.НомерДок = НомерЗаявки Тогда
Док.ВыбратьСтроки();
Пока Док.ПолучитьСтроку()=1 Цикл
нов=Таблица.Добавить();
нов.Номенклатура = Док.Номенклатура.Наименование;
нов.Количество = Док.Количество;
нов.Единица = Док.Единица.Наименование;
нов.Цена = Док.Цена;
Нов.Сумма = Док.Сумма;
нов.Коэффициент = Док.Коэффициент;
нов.Производитель = Док.производитель;
Нов.Валюта = Док.Валюта.Наименование;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Док=NULL;
КонецПроцедуры
Код 1C v 8.2 УП //Примеры получения значений
//Периодический реквизит нужно получать на дату
ДатаОст= ТекущаяДата();
Спр77Оле.ВидГрейда.Получить(ДатаОст).код;
// Перечисление
Если База77ОЛЕ.ВидКонтрагента.Идентификатор() = "ЧастноеЛицо"
// или
Если Сотрудник.ХарактерРаботы.Получить(Необходимая_Дата).Идентификатор() = БазаОЛЕ.EvalExpr("Перечисление.ХарактерРаботы.ТрудовыеОтношения.Идентификатор()") Тогда
// Принадлежит ...
КонецЕсли;
//В запросе
// в v7 ссылка OLE
Запрос = v7.CreateObject("Запрос");
ТипТовара = v7.evalexpr("Перечисление.ТипыТоваров.Собственный.ПорядковыйНомер()");
ТекстЗапроса =
"//{{ЗАПРОС(Сформировать)
|ТекущийЭлемент = Справочник.Номенклатура.ТекущийЭлемент;
|Наименование = Справочник.Номенклатура.Наименование;
|ТипТовара = Справочник.Номенклатура.ТипТовара;
|ЕдиницаИзмерения = Справочник.Номенклатура.ЕдиницаИзмерения;
|Функция Счётчик = Счётчик();
|Группировка ТекущийЭлемент;
|Условие(ТипТовара.ПорядковыйНомер() = "+ТипТовара+");
|"//}}ЗАПРОС
;
Категория:
COM-объекты, WMI, WSH Получение базовых данных в регистрах расчета При работе с регистрами расчета есть возможность получения базовых данных. Это своеобразный способ расчета оборотов регистра, при котором функция расчета оборотов не является простой функцией суммирования ресурсов регистра по измерениям за определенный период, а представляет собой более сложную функцию. Эта функция зависит от состояния плана видов расчета, назначенного регистру расчета и, таким образом, управляется пользователем.
В данном разделе мы рассмотрим два существующих в системе способа получения базовых данных - при помощи языка запросов и при помощи функциональной записи, методом
ПолучитьБазу() . При этом будет называть "основным" регистром расчета тот регистр, для которого необходимо получить базовые данные, а "базовыми" регистрами (которых в общем случае может быть несколько) будем называть те регистры, для которых выполняется суммирование ресурсов.
Мы не будем рассматривать эти способы подробно, рассмотрим только их отличия и область применения.
Метод ПолучитьБазу()
Метод
ПолучитьБазу() определен для объектов
РегистрРасчетаМенеджер.<Имя регистра расчета> и
РегистрРасчетаЗапись.<Имя регистра расчета> . Метод позволяет задать ресурсы базовых регистров, по которым необходимо получить обороты, задать поля, в разрезе которых нужно получить обороты и задать правила сопоставления измерений основного и базовых регистров расчета.
Правила сопоставления записей регистров расчета задаются структурой, каждый элемент которой задает для того или иного измерения основного регистра список измерений базовых регистров расчета. Имена элементов структуры должны совпадать с именами измерений основного регистра, а значения элементов структуры - строки, со списком измерений базовых регистров через запятую. Если элемент структуры с именем того или иного измерения не задан, то это значит, что на соответствующее измерение не налагается условие.
Имена измерений и ресурсов базовых регистров задаются в формате <ИмяРегистраРасчета>.<ИмяПоля>.
Пример использования метода:
Код 1C v 8.х Ресурсы = Новый Массив(1);
Ресурсы[0] = "ОсновныеНачисления.Результат,ДополнительныеНачисления.Результат";
Измерения = Новый Структура("ФизЛицо,Организация");
Измерения.ФизЛицо = "ОсновныеНачисления.Физлицо,ДополнительныеНачисления.Работник";
Измерения.Организация = "ОсновныеНачисления.Организация,ДополнительныеНачисления.Организация";
Разрезы = Новый Массив(1);
Разрезы[0] = "ОсновныеНачисления.Способ,ДополнительныеНачисления.Способ";
// Рассчитываем базуТаблицаБазовыхДанных = РегистрРасчета.Удержания.ПолучитьБазу(Отбор,
// Ресурсы, Измерения, Разрезы);
В приведенном выше примере измерение "Физлицо" основного регистра при получении оборотов будет сопоставляться с измерением "Физлицо" базового регистра "ОсновныеНачисления" и измерением "Работник" базового регистра "ДополнительныеНачисления".
Таблица языка запросов для получения базовых данных
Для получения базовых данных в языке запросов определены виртуальные таблицы
"РегистрРасчета.<Имя регистра расчета>.База<Имя базового регистра расчета>" . В качестве параметров виртуальной таблицы задаются измерения основного регистра, измерения базового регистра и поля, в разрезе которых нужно получить базовые данные. Измерения и разрезы задаются как массив (или список значений) строк с именами измерений.
Пример написания запроса с использованием виртуальных таблиц базовых данных:
Код 1C v 8.х
Измерения1 = Массив(2);
Измерения1[0] = "Физлицо";
Измерения1[1] = "Организация";
Измерения2 = Массив(2);
Измерения2[0] = "Работник";
Измерения2[1] = "Организация";
Разрезы = Новый Массив(1);
Разрезы[0] = "Способ";
ТекстЗапроса = "ВЫБРАТЬ Физлицо, ВидРасчета, СУММА(РезультатБаза)
|ИЗ
|(
|ВЫБРАТЬ Физлицо, ВидРасчета, РезультатБаза
| ИЗ РегистрРасчета.Удержания.БазаОсновныеНачисления(&Измерения1,&Измерения1,&Разрезы)
|ГДЕ " + УсловиеОсновных + "
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ Работник, ВидРасчета, РезультатБаза
| ИЗ РегистрРасчета.Удержания.БазаДополнительныеНачисления(&Измерения1,&Измерения2,&Разрезы)
|ГДЕ " + УсловиеДополнительных + "
|) КАК База
|СГРУППИРОВАТЬ ПО
| Физлицо,
| ВидРасчета
|";
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("Измерения1", Измерения1);
Запрос.УстановитьПараметр("Измерения2", Измерения2);
Запрос.УстановитьПараметр("Разрезы", Разрезы);
// ...установка дополнительных параметров запроса, применяемых в условиях в операторе ГДЕ// ,..
// получим выборку результата запросаВыборка = Запрос.Выполнить().Выбрать();
Приведенный пример предполагает ту же структуру данных и ту же решаемую задачу, что и пример для метода ПолучитьБазу(). При этом мы видим заметное увеличение исходного кода и кажущуюся его сложность.
Сравнение
Заметным отличием функционального метода получения базовых данных и получения при помощи запроса является то, что в функциональном методе одним вызовом метода можно получить базовые данные по всем базовым регистрам, а при использовании запросов получение базовых данных делается запросом к нескольким таблицам - по числу базовых регистров. Тем не менее, рекомендуемым способом получения данных является получение данных запросом. Это позволит, например, получить не только данные базовых видов расчета, но и дополнительную информацию, необходимую для расчета.
Отметим, что производительность получения данных при помощи функционального метода и при помощи запроса одинакова несмотря на кажущееся усложнение исполняемого кода в случае с запросами.
Краткая функциональная запись с использованием метода ПолучитьБазу() допустима только в том случае, если нет необходимости в иных данных помимо базовых, и при этом хочется "сэкономить" на строках кода. Совершенно не допустимо из соображений производительности кода, применение метода ПолучитьБазу() в том случае, если после его использование все равно придется при помощи запроса получать дополнительные данные для расчета.
Еще одно соображение касается условий отбора базовых данных. Для метода ПолучитьБазу(), фактически, нет возможности получить базовые данные иначе, чем по одной записи или по конкретному регистратору (с отбором по тем или иным измерениям). В случае же запроса в распоряжении у разработчика все возможности языка запросов по отбору записей.
Категория:
Регистры расчета Как получить результат запроса в web таблицу используя Web сервис? Медитируя на тему почему нет нормальной “Консоли запросов в управляемом приложении” захотелось покопаться в этих внутренностях 1С.
Как ставить и настраивать вэб-сервис в 1С, я не буду расказывать. Вы это легко найдете.
Идея такая: почему бы нам не создать вэб-сервис, который на строку запроса 1С выдаст web таблицу(с тэгами…). Заморачиваться с XTDO не советую, капризный он. Выдаем ответ сервера в виде строки. Данные в таблице для простоты тоже сделаем текстовыми (html).
Сделаем конфигурацию в которой один вэб-сервис (Прикреплен к статье). И распишем функцию подробно,чтобы ее можно было подключить к любой конфигурации вручную.
Все парамеры в функции строковые
Request1C – текст запроса
TableData – html строка ответа.
Возвращаем истина или ложь;
Код 1C v 8.2 УП //Возврат результата запроса в web table
Функция Request1CWebTable(Request1C, ТableData)
Запрос = Новый Запрос;
ТableData = “”;
Сериализатор = Новый СериализаторXDTO(ФабрикаXDTO);
ТекстЗапроса = Сериализатор.ПрочитатьXDTO(Request1C);
Запрос.Текст = ТекстЗапроса;
//Результат – таблица значений
Попытка
ТабЗапроса = Запрос.Выполнить().Выгрузить();
Исключение
ЗаписьЖурналаРегистрации(“Request1C”,,,,Строка(Request1C) + ” !!! “+ОписаниеОшибки());
Возврат Ложь;
Конецпопытки;
//строка заголовка
ТableData = ““;
Для каждого колонка Из ТабЗапроса.Колонки Цикл
ТableData = ТableData + “”+ СокрЛП(колонка.Заголовок) + “”;
КонецЦикла;
ТableData = ТableData + “”;
//таблица данных
ТableData = ТableData + “”;
Для строка=0 По ТабЗапроса.Количество()-1 Цикл
ТableData = ТableData + “”;
Для кол=0 По ТабЗапроса.колонки.Количество()-1 Цикл
ТableData = ТableData + “”+ Строка(ТабЗапроса[строка][кол]) + “”;
КонецЦикла;
ТableData = ТableData + “”;
КонецЦикла;
ТableData = ТableData + “”;
ТабЗапроса = 0;
Возврат Истина;
КонецФункции
Публикуем web-сервис c именем
testws . Для тестирования уберем из базы всех пользователей, включаем анонимную идентификацию и смотрим чтобы ресурс
htp://localhost/testws/ws/testws?wsdl был доступен из браузера. Если показывает в браузере описание вэб-сервиса, значит все нормально.
Это все хорошо, но как все это показать? Сделаем страницу входа для обработки в вашем любимом Web-сервере. Или просто бросьте папку test1C в папку C:\inetpub\wwwroot для MS IIS(Internet Information Server)
Вы не разбираетесь в Web программировании – не беда. Главное усвоить основы. Мы посылаем специально подготовленный post запрос в Web-сервер, он передает его 1С и возращает ответ. И нам в браузере необходимо обработать ответ сервера.
Запрос:
Код var soapEnv = ‘ ‘; soapEnv += ”;
soapEnv += $(‘#textRequest’).val(); soapEnv += ”;
#textRequest – поле нашего запроса.
Вырезаем из ответа сервера необходимое и преобразуем назад спец символы < и > на < и >.
Код var strBegin = “< ; table id=’result_table’”;
var strEnd = “</m:TableData>”;
dataResponce = dataResponce.substring(dataResponce.indexOf(strBegin), dataResponce.indexOf(strEnd));
$(‘#result’).html(htmlspecialchars_decode(dataResponce));
Спасибо авторам библиотек jquery.com и tablesorter.com и их лицензиям(GPL, MIT) за их открытость. С помощью jquery не надо писать разный код под разные браузеры(они к сожалению различаются). А tablesorter используем для просоты вывода…
Заходим в браузер http://localhost/test1C и пишем запрос… Правильно написать запрос у меня не получается, я всегда копирую его из консоли запросов.
Нажимаем кнопку. И приходит к нам счастье.
Дополнительно скажу, что для слишком больших результатов запросов данная схема может не работать. У меня где-то начинала не выводить или выводить неправильно к 10000-100000 записям. Скорее всего ответ сервера посто не залезает в один пакет soap. А если отключить сжатие пакетов я думаю будет еще хуже. Так, что будьте осторожны.
Скачать обработку :
Скачивать файлы может только зарегистрированный пользователь!
P.S.
Ну очень грубо говоря так и работает 1С тонкий и web-клиент
Автор:
sikuda Категория:
WEB-сервисы, WS-ссылки, XDTO-пакеты Как быстро вывести результат Запроса в табличный документ? Код 1C v 8.х // Можно результат запроса, а можно и таблицу значений.
ТекстЗапроса = "ВЫБРАТЬ * ИЗ Справочник.Пользователи";
ЗапросаДанных = Новый Запрос(ТекстЗапроса);
РезЗапроса = ЗапросаДанных.Выполнить();
ТабДокумент = Новый ТабличныйДокумент;
Построитель = Новый ПостроительОтчета;
Построитель.ИсточникДанных=Новый ОписаниеИсточникаДанных(РезЗапроса);
Построитель.Вывести(ТабДокумент);
ТабДокумент.Показать("Пользователи");
Категория:
Запросы Как быстро вывести таблицу значений в табличный документ? Код 1C v 8.х ТекстЗапроса = "ВЫБРАТЬ * ИЗ Справочник.Пользователи";
ЗапросаДанных = Новый Запрос(ТекстЗапроса);
РезЗапроса = ЗапросаДанных.Выполнить().Выгрузить();
ТабДокумент = Новый ТабличныйДокумент;
Построитель = Новый ПостроительОтчета;
Построитель.ИсточникДанных=Новый ОписаниеИсточникаДанных(РезЗапроса);
Построитель.Вывести(ТабДокумент);
ТабДокумент.Показать("Пользователи");
Категория:
Работа с Таблицей Значений Универсальный отчет в прикладных решениях фирмы 1С Как настроить Универсальный отчет?
Все настройки
универсального отчета описываются в процедуре
УстановитьНачальныеНастройки :
Код 1C v 8.х Процедура УстановитьНачальныеНастройки(ДополнительныеПараметры = Неопределено) Экспорт
// Настройка общих параметров универсального отчета
//начальный вариант оформления цветовой схемы
УниверсальныйОтчет.ВариантОформления = СтандартноеОформление.Песок;
// Содержит название отчета, которое будет выводиться в шапке.
// Тип: Строка.
// Пример:
// УниверсальныйОтчет.мНазваниеОтчета = "Название отчета";
УниверсальныйОтчет.мНазваниеОтчета = СокрЛП(ЭтотОбъект.Метаданные().Синоним);
// Содержит признак необходимости отображения надписи и поля выбора раздела учета в форме настройки.
// Тип: Булево.
// Значение по умолчанию: Истина.
// Пример:
// УниверсальныйОтчет.мВыбиратьИмяРегистра = Ложь;
УниверсальныйОтчет.мВыбиратьИмяРегистра = Ложь;
// Содержит имя регистра, по метаданным которого будет выполняться заполнение настроек отчета.
// Тип: Строка.
// Пример:
// УниверсальныйОтчет.ИмяРегистра = "ТоварыНаСкладах";
УниверсальныйОтчет.ИмяРегистра = "-";
// Содержит признак необходимости вывода отрицательных значений показателей красным цветом.
// Тип: Булево.
// Значение по умолчанию: Ложь.
// Пример:
// УниверсальныйОтчет.ОтрицательноеКрасным = Истина;
УниверсальныйОтчет.ОтрицательноеКрасным = Истина;
// Содержит признак необходимости вывода в отчет общих итогов.
// Тип: Булево.
// Значение по умолчанию: Истина.
// Пример:
// УниверсальныйОтчет.ВыводитьОбщиеИтоги = Ложь;
УниверсальныйОтчет.ВыводитьОбщиеИтоги = Истина;
// Содержит признак необходимости вывода детальных записей в отчет.
// Тип: Булево.
// Значение по умолчанию: Ложь.
// Пример:
// УниверсальныйОтчет.ВыводитьДетальныеЗаписи = Истина;
УниверсальныйОтчет.ВыводитьДетальныеЗаписи = Ложь;
// Содержит признак необходимости отображения флага использования свойств и категорий в форме настройки.
// Тип: Булево.
// Значение по умолчанию: Истина.
// Пример:
// УниверсальныйОтчет.мВыбиратьИспользованиеСвойств = Ложь;
УниверсальныйОтчет.мВыбиратьИспользованиеСвойств = Истина;
// Содержит признак использования свойств и категорий при заполнении настроек отчета.
// Тип: Булево.
// Значение по умолчанию: Ложь.
// Пример:
// УниверсальныйОтчет.ИспользоватьСвойстваИКатегории = Истина;
//УниверсальныйОтчет.ИспользоватьСвойстваИКатегории = ЛОЖЬ;
// Содержит признак использования простой формы настроек отчета без группировок колонок.
// Тип: Булево.
// Значение по умолчанию: Ложь.
// Пример:
// УниверсальныйОтчет.мРежимФормыНастройкиБезГруппировокКолонок = Истина;
// Дополнительные параметры, переданные из отчета, вызвавшего расшифровку.
// Информация, передаваемая в переменной ДополнительныеПараметры, может быть использована
// для реализации специфичных для данного отчета параметрических настроек.
// Описание исходного текста запроса.
ТекстЗапроса = "ВЫБРАТЬ РАЗРЕШЕННЫЕ
| CRM_ПредложенияОбороты.Номенклатура КАК Номенклатура,
| ПРЕДСТАВЛЕНИЕ(CRM_ПредложенияОбороты.Номенклатура) КАК НоменклатураПредставление,
| CRM_ПредложенияОбороты.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ПРЕДСТАВЛЕНИЕ(CRM_ПредложенияОбороты.ХарактеристикаНоменклатуры) КАК ХарактеристикаНоменклатурыПредставление,
| CRM_ПредложенияОбороты.Контрагент КАК Контрагент,
| ПРЕДСТАВЛЕНИЕ(CRM_ПредложенияОбороты.Контрагент) КАК КонтрагентПредставление,
| CRM_ПредложенияОбороты.ДокументПредложения КАК Документ,
| ПРЕДСТАВЛЕНИЕ(CRM_ПредложенияОбороты.ДокументПредложения) КАК ДокументПредставление,
| CRM_ПредложенияОбороты.ДокументПредложения.Ответственный КАК Ответственный,
| ПРЕДСТАВЛЕНИЕ(CRM_ПредложенияОбороты.ДокументПредложения.Ответственный) КАК ОтветственныйПредставление,
| CRM_ПредложенияОбороты.КоличествоОборот КАК КоличествоОборот,
| CRM_ПредложенияОбороты.СтоимостьОборот КАК СтоимостьОборот,
| 0 КАК СкидкаОборот,
| 1 КАК Количество,
| CRM_ПредложенияОбороты.СтоимостьБезСкидокОборот КАК СтоимостьБезСкидокОборот
| //ПОЛЯ_СВОЙСТВА
| //ПОЛЯ_КАТЕГОРИИ
|{ВЫБРАТЬ
| Контрагент.*,
| Номенклатура.*,
| ХарактеристикаНоменклатуры.*,
| Ответственный.*,
| Документ.*,
| КоличествоОборот,
| СтоимостьОборот,
| СкидкаОборот,
| Количество,
| (ЕСТЬNULL(ИсточникиИнформацииПриОбращении.ИсточникИнформации,ЗНАЧЕНИЕ(Справочник.ИсточникиИнформацииПриОбращенииПокупателей.ПустаяСсылка))).* КАК ИсточникИнформации
| //ПСЕВДОНИМЫ_СВОЙСТВА
| //ПСЕВДОНИМЫ_КАТЕГОРИИ
|}
|ИЗ
| РегистрНакопления.CRM_Предложения.Обороты(&ДатаНач, &ДатаКон, , ) КАК CRM_ПредложенияОбороты
|{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ИсточникИнформацииПриОбращении.СрезПоследних(&ДатаКон) КАК ИсточникиИнформацииПриОбращении
|ПО CRM_ПредложенияОбороты.Контрагент = ИсточникиИнформацииПриОбращении.Контрагент}
|//СОЕДИНЕНИЯ
|{ГДЕ
| CRM_ПредложенияОбороты.Контрагент.* КАК Контрагент,
| CRM_ПредложенияОбороты.Номенклатура.* КАК Номенклатура,
| CRM_ПредложенияОбороты.ХарактеристикаНоменклатуры.* КАК ХарактеристикаНоменклатуры,
| CRM_ПредложенияОбороты.ДокументПредложения.Ответственный.* КАК Ответственный,
| CRM_ПредложенияОбороты.ДокументПредложения.* КАК Документ,
| (ЕСТЬNULL(ИсточникиИнформацииПриОбращении.ИсточникИнформации,ЗНАЧЕНИЕ(Справочник.ИсточникиИнформацииПриОбращенииПокупателей.ПустаяСсылка))).* КАК ИсточникИнформации
| //УСЛОВИЯ_СВОЙСТВА
| //УСЛОВИЯ_КАТЕГОРИИ
|}
|{УПОРЯДОЧИТЬ ПО
| Контрагент.*,
| Номенклатура.*,
| ХарактеристикаНоменклатуры.*,
| Ответственный.*,
| Документ.*,
| (ЕСТЬNULL(ИсточникиИнформацииПриОбращении.ИсточникИнформации,ЗНАЧЕНИЕ(Справочник.ИсточникиИнформацииПриОбращенииПокупателей.ПустаяСсылка))).* КАК ИсточникИнформации
| //ПСЕВДОНИМЫ_СВОЙСТВА
| //ПСЕВДОНИМЫ_КАТЕГОРИИ
|}
|
|ИТОГИ
| СУММА(КоличествоОборот),
| СУММА(СтоимостьОборот),
| СУММА(СтоимостьБезСкидокОборот - СтоимостьОборот) КАК СкидкаОборот,
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ(Документ)) КАК Количество
|ПО
| ОБЩИЕ
|{ИТОГИ ПО
| Контрагент.*,
| Номенклатура.*,
| ХарактеристикаНоменклатуры.*,
| Ответственный.*,
| Документ.*,
| (ЕСТЬNULL(ИсточникиИнформацииПриОбращении.ИсточникИнформации,ЗНАЧЕНИЕ(Справочник.ИсточникиИнформацииПриОбращенииПокупателей.ПустаяСсылка))).* КАК ИсточникИнформации,
| НАЧАЛОПЕРИОДА(CRM_ПредложенияОбороты.ДокументПредложения.Дата, ДЕНЬ) КАК ПериодДень,
| НАЧАЛОПЕРИОДА(CRM_ПредложенияОбороты.ДокументПредложения.Дата, НЕДЕЛЯ) КАК ПериодНеделя,
| НАЧАЛОПЕРИОДА(CRM_ПредложенияОбороты.ДокументПредложения.Дата, МЕСЯЦ) КАК ПериодМесяц,
| НАЧАЛОПЕРИОДА(CRM_ПредложенияОбороты.ДокументПредложения.Дата, КВАРТАЛ) КАК ПериодКвартал,
| НАЧАЛОПЕРИОДА(CRM_ПредложенияОбороты.ДокументПредложения.Дата, ГОД) КАК ПериодГод
| //ПСЕВДОНИМЫ_СВОЙСТВА
| //ПСЕВДОНИМЫ_КАТЕГОРИИ
|}";
// В универсальном отчете включен флаг использования свойств и категорий.
Если УниверсальныйОтчет.ИспользоватьСвойстваИКатегории Тогда
// Добавление свойств и категорий поля запроса в таблицу полей.
// Необходимо вызывать для каждого поля запроса, предоставляющего возможность использования свойств и категорий.
// УниверсальныйОтчет.ДобавитьСвойстваИКатегорииДляПоля(<ПсевдонимТаблицы>.<Поле> , <ПсевдонимПоля>, <Представление>, <Назначение>);
УниверсальныйОтчет.ДобавитьСвойстваИКатегорииДляПоля("CRM_ПредложенияОбороты.Номенклатура" , "Номенклатура", "Номенклатура", ПланыВидовХарактеристик.НазначенияСвойствКатегорийОбъектов.Справочник_Номенклатура);
УниверсальныйОтчет.ДобавитьСвойстваИКатегорииДляПоля("CRM_ПредложенияОбороты.ХарактеристикаНоменклатуры" , "ХарактеристикаНоменклатуры", "Характеристика номенклатуры", ПланыВидовХарактеристик.НазначенияСвойствКатегорийОбъектов.Справочник_Номенклатура);
УниверсальныйОтчет.ДобавитьСвойстваИКатегорииДляПоля("CRM_ПредложенияОбороты.Контрагент" , "Контрагент", "Контрагент", ПланыВидовХарактеристик.НазначенияСвойствКатегорийОбъектов.Справочник_Номенклатура);
УниверсальныйОтчет.ДобавитьСвойстваИКатегорииДляПоля("CRM_ПредложенияОбороты.ДокументПредложения" , "Документ", "Коммерческое предложение", ПланыВидовХарактеристик.НазначенияСвойствКатегорийОбъектов.Документ_CRM_КоммерческоеПредложение);
// Добавление свойств и категорий в исходный текст запроса.
УниверсальныйОтчет.ДобавитьВТекстЗапросаСвойстваИКатегории(ТекстЗапроса);
КонецЕсли;
// Инициализация текста запроса построителя отчета
УниверсальныйОтчет.ПостроительОтчета.Текст = ТекстЗапроса;
// Представления полей отчета.
// Необходимо вызывать для каждого поля запроса.
// УниверсальныйОтчет.мСтруктураПредставлениеПолей.Вставить(<ИмяПоля>, <ПредставлениеПоля>);
УниверсальныйОтчет.мСтруктураПредставлениеПолей.Вставить("ХарактеристикаНоменклатуры", "Характеристика номенклатуры");
УниверсальныйОтчет.мСтруктураПредставлениеПолей.Вставить("Документ", "Коммерческое предложение");
УниверсальныйОтчет.мСтруктураПредставлениеПолей.Вставить("ИсточникИнформации", "Источник информации при обращении покупателя");
// Добавление показателей
// Необходимо вызывать для каждого добавляемого показателя.
// УниверсальныйОтчет.ДобавитьПоказатель(<ИмяПоказателя>, <ПредставлениеПоказателя>, <ВключенПоУмолчанию>, <Формат>, <ИмяГруппы>, <ПредставлениеГруппы>);
//УниверсальныйОтчет.ДобавитьПоказатель("Задача", "Задача", Истина,);
УниверсальныйОтчет.ДобавитьПоказатель("Количество", "Количество документов", Истина, "ЧЦ = 15 ; ЧДЦ = 3");
УниверсальныйОтчет.ДобавитьПоказатель("КоличествоОборот", "Количество номенклатуры", Истина, "ЧЦ = 15 ; ЧДЦ = 3",,);
УниверсальныйОтчет.ДобавитьПоказатель("СтоимостьОборот", "Сумма", Истина, "ЧЦ = 15 ; ЧДЦ = 2");
УниверсальныйОтчет.ДобавитьПоказатель("СкидкаОборот", "Скидка", Истина, "ЧЦ = 15 ; ЧДЦ = 2",,);
// Добавление предопределенных группировок строк отчета.
// Необходимо вызывать для каждой добавляемой группировки строки.
// УниверсальныйОтчет.ДобавитьИзмерениеСтроки(<ПутьКДанным>);
УниверсальныйОтчет.ДобавитьИзмерениеСтроки("Контрагент");
УниверсальныйОтчет.ДобавитьИзмерениеСтроки("Номенклатура");
// Добавление предопределенных группировок колонок отчета.
// Необходимо вызывать для каждой добавляемой группировки колонки.
// УниверсальныйОтчет.ДобавитьИзмерениеКолонки(<ПутьКДанным>);
// Добавление предопределенных отборов отчета.
// Необходимо вызывать для каждого добавляемого отбора.
// УниверсальныйОтчет.ДобавитьОтбор(<ПутьКДанным>);
УниверсальныйОтчет.ДобавитьОтбор("Контрагент");
УниверсальныйОтчет.ДобавитьОтбор("Номенклатура");
УниверсальныйОтчет.ДобавитьОтбор("Ответственный");
УниверсальныйОтчет.ДобавитьОтбор("Документ");
// Добавление предопределенных полей порядка отчета.
// Необходимо вызывать для каждого добавляемого поля порядка.
// УниверсальныйОтчет.ДобавитьПорядок(<ПутьКДанным>);
// Установка связи подчиненных и родительских полей
// УниверсальныйОтчет.УстановитьСвязьПолей(<ПутьКДанным>, <ПутьКДаннымРодитель>);
//УниверсальныйОтчет.УстановитьСвязьПолей("ТочкаМаршрута","Задача");
// Установка связи полей и измерений
// УниверсальныйОтчет.УстановитьСвязьПоляИИзмерения(<ИмяПоля>, <ИмяИзмерения>);
// Установка представлений полей
УниверсальныйОтчет.УстановитьПредставленияПолей(УниверсальныйОтчет.мСтруктураПредставлениеПолей, УниверсальныйОтчет.ПостроительОтчета);
// Установка типов значений свойств в отборах отчета
УниверсальныйОтчет.УстановитьТипыЗначенийСвойствДляОтбора();
// Заполнение начальных настроек универсального отчета
УниверсальныйОтчет.УстановитьНачальныеНастройки(Ложь);
// Добавление предопределенных отборов отчета.
// Необходимо вызывать для каждого добавляемого отбора.
// УниверсальныйОтчет.ДобавитьОтбор(<ПутьКДанным>);
УниверсальныйОтчет.ДобавитьОтбор("Контрагент");
УниверсальныйОтчет.ДобавитьОтбор("Номенклатура");
УниверсальныйОтчет.ДобавитьОтбор("Ответственный");
УниверсальныйОтчет.ДобавитьОтбор("Документ");
// Добавление дополнительных полей
// Необходимо вызывать для каждого добавляемого дополнительного поля.
// УниверсальныйОтчет.ДобавитьДополнительноеПоле(<ПутьКДанным>, <Размещение>, <Положение>);
УниверсальныйОтчет.мСтруктураФорматаПолей.Вставить("ДатаВыполнения", "ДЛФ=DDT");
УниверсальныйОтчет.мСтруктураФорматаПолей.Вставить("ДатаФактическогоВыполнения", "ДЛФ=DDT");
УниверсальныйОтчет.мМинимальнаяШиринаКолонкиПоказатель = 10;
УниверсальныйОтчет.мМаксимальнаяШиринаКолонки = 80;
КонецПроцедуры // УстановитьНачальныеНастройки()
Как настроить условное оформление в Универсальном отчете?
Выравнивание значений влево :
Код 1C v 8.х ЭлементОформления = УниверсальныйОтчет.ПостроительОтчета.УсловноеОформление.Добавить("Номенклатура", "Номенклатура");
ЭлементОформления.Область.Добавить("Номенклатура", "Номенклатура", ТипОбластиОформления.Поле);
ЭлементОформления.Оформление.ГоризонтальноеПоложение.Значение = ГоризонтальноеПоложение.Лево;
ЭлементОформления.Оформление.ГоризонтальноеПоложение.Использование = Истина;
ЭлементОформления.Использование = Истина;
ЭлементОформления = УниверсальныйОтчет.ПостроительОтчета.УсловноеОформление.Добавить("ХарактеристикаНоменклатуры", "ХарактеристикаНоменклатуры");
ЭлементОформления.Область.Добавить("ХарактеристикаНоменклатуры", "ХарактеристикаНоменклатуры", ТипОбластиОформления.Поле);
ЭлементОформления.Оформление.ГоризонтальноеПоложение.Значение = ГоризонтальноеПоложение.Лево;
ЭлементОформления.Оформление.ГоризонтальноеПоложение.Использование = Истина;
ЭлементОформления.Использование = Истина;
УниверсальныйОтчет.мМинимальнаяШиринаКолонкиПоказатель = 7;
УниверсальныйОтчет.мМаксимальнаяШиринаКолонки = 50;
Изменение цвета текста и т.д.
Код 1C v 8.х // Условное оформление поля "Состояние"
ЭлементОформления = УниверсальныйОтчет.ПостроительОтчета.УсловноеОформление.Добавить("ТребуетсяЗаказать", "Требуется заказать");
ЭлементОформления.Область.Добавить("Состояние", "Состояние", ТипОбластиОформления.Поле);
ЭлементОтбора = ЭлементОформления.Отбор.Добавить("Состояние");
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
ЭлементОтбора.Значение = 0;
ЭлементОтбора.Использование = Истина;
ЭлементОформления.Оформление.ЦветТекста.Значение = WebЦвета.Красный;
ЭлементОформления.Оформление.ЦветТекста.Использование = Истина;
ЭлементОформления.Оформление.Текст.Значение = "Требуется заказать";
ЭлементОформления.Оформление.Текст.Использование = Истина;
ЭлементОформления.Использование = Истина;
ЭлементОформления = УниверсальныйОтчет.ПостроительОтчета.УсловноеОформление.Добавить("РекомендуетсяЗаказать", "Рекомендуется заказать");
ЭлементОформления.Область.Добавить("Состояние", "Состояние", ТипОбластиОформления.Поле);
ЭлементОтбора = ЭлементОформления.Отбор.Добавить("Состояние");
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
ЭлементОтбора.Значение = 1;
ЭлементОтбора.Использование = Истина;
ЭлементОформления.Оформление.ЦветТекста.Значение = WebЦвета.Коричневый;
ЭлементОформления.Оформление.ЦветТекста.Использование = Истина;
ЭлементОформления.Оформление.Текст.Значение = "Рекомендуется заказать";
ЭлементОформления.Оформление.Текст.Использование = Истина;
ЭлементОформления.Использование = Истина;
ЭлементОформления = УниверсальныйОтчет.ПостроительОтчета.УсловноеОформление.Добавить("НеТребуетсяЗаказывать", "Не требуется заказывать");
ЭлементОформления.Область.Добавить("Состояние", "Состояние", ТипОбластиОформления.Поле);
ЭлементОтбора = ЭлементОформления.Отбор.Добавить("Состояние");
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
ЭлементОтбора.Значение = 2;
ЭлементОтбора.Использование = Истина;
ЭлементОформления.Оформление.ЦветТекста.Значение = WebЦвета.Зеленый;
ЭлементОформления.Оформление.ЦветТекста.Использование = Истина;
ЭлементОформления.Оформление.Текст.Значение = "Не требуется заказывать";
ЭлементОформления.Оформление.Текст.Использование = Истина;
ЭлементОформления.Использование = Истина;
ЭлементОформления = УниверсальныйОтчет.ПостроительОтчета.УсловноеОформление.Добавить("ЗонаПоСумме", "Зона По Сумме");
ЭлементОформления.Область.Добавить("ЗонаПоСумме", "ЗонаПоСумме", ТипОбластиОформления.Поле);
ЭлементОтбора = ЭлементОформления.Отбор.Добавить("ЗонаПоСумме");
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
ЭлементОтбора.Значение = "крас";
ЭлементОтбора.Использование = Истина;
ЭлементОформления.Оформление.ЦветФона.Значение = WebЦвета.Красный;
ЭлементОформления.Оформление.ЦветФона.Использование = Истина;
ЭлементОформления.Оформление.Текст.Значение = "";
ЭлементОформления.Оформление.Текст.Использование = Истина;
ЭлементОформления.Использование = Истина;
ЭлементОформления = УниверсальныйОтчет.ПостроительОтчета.УсловноеОформление.Добавить("ЗонаПоСумме", "Зона По Сумме");
ЭлементОформления.Область.Добавить("ЗонаПоСумме", "ЗонаПоСумме", ТипОбластиОформления.Поле);
ЭлементОтбора = ЭлементОформления.Отбор.Добавить("ЗонаПоСумме");
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
ЭлементОтбора.Значение = "зелн";
ЭлементОтбора.Использование = Истина;
ЭлементОформления.Оформление.ЦветТекста.Значение = WebЦвета.Зеленый;
ЭлементОформления.Оформление.ЦветТекста.Использование = Истина;
ЭлементОформления.Оформление.Шрифт.Значение = Новый Шрифт(,,Истина);
ЭлементОформления.Оформление.Шрифт.Использование = Истина;
ЭлементОформления.Оформление.Текст.Значение = "|||||||||||||||||";
ЭлементОформления.Оформление.Текст.Использование = Истина;
ЭлементОформления.Использование = Истина;
Для типа «Дата»:
Код 1C v 8.х ЭлементОформления = УниверсальныйОтчет.ПостроительОтчета.УсловноеОформление.Добавить("ДатаЗаписи", "Дата записи");
ЭлементОформления.Область.Добавить("ДатаЗаписи", "Дата записи", ТипОбластиОформления.Поле);
ЭлементОформления.Оформление.Формат.Значение = "ДФ=dd.MM.yyyy";
ЭлементОформления.Оформление.Формат.Использование = Истина;
ЭлементОформления.Использование = Истина;
Для типа «Булево»:
Код 1C v 8.х ЭлементОформления = УниверсальныйОтчет.ПостроительОтчета.УсловноеОформление.Добавить("Печать", "Печать");
ЭлементОформления.Область.Добавить("Печать", "Печать", ТипОбластиОформления.Поле);
ЭлементОформления.Оформление.ГоризонтальноеПоложение.Значение = ГоризонтальноеПоложение.Центр;
ЭлементОформления.Оформление.Формат.Значение = «БЛ=Нет; БИ=Напечатан»;
ЭлементОформления.Оформление.ГоризонтальноеПоложение.Использование = Истина;
ЭлементОформления.Использование = Истина;
Категория:
Прочие вопросы Как подключиться к базе 1С 8.х из 1С 7.7 ? Код 1C v 7.x //Инициализация соединения в 7.7:
Коннектор=Создать0бъект("V82.COMConnector");
// Для 8.1 ("V81.COMConnector");
// для 8.0 ("V8.COMConnector");
// создается объект COM -соединение Соединение = V8.Connect ("File=""c:\InfoBases\Trade""; Usr =""Director"";")
v8 =Коннектор.Connect("File="""+СокрЛП(ПутьКБазе) + """; Usr="""СокрЛП(Логин) +"""; Pwd=""" +СокрЛП(Пароль)+""" ");
где переменные ПутьКБазе, Логин, Пароль — поля на форме.
После выполнения подключения имеем объект v8, через который можно обращаться к свойствам и методам нужной базы.
Допустим в 8.х есть экспортная функция возвращающая выборку документов:
Код 1C v 8.х Функция ВернутьВыборкуДокументов(ИмяДокумента,Дата1,Дата2) Экспорт
Запрос = Новый Запрос;
ТекстЗапроса =
"ВЫБРАТЬ
| Док.Ссылка КАК {ИмяДокумента}
|ИЗ
| Документ. {ИмяДокумента} КАК Док
|ГДЕ
| Док.Дата МЕЖДУ &Дата1 И &Дата2";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса,"{ИмяДокумента}",ИмяДокумента);
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("Дата1",Дата1);
Запрос.УстановитьПараметр("Дата2",Дата2);
Выборка = Запрос.Выполнить().Выбрать();
Возврат Выборка;
Из 7.7 через
Коннектор обращаемся к ней так:
Код 1C v 7.x Выборка = v8.ВернутьВыборкуДокументов("РеализацияТоваров", ДатаС,ДатаПо);
Пока Выборка.Следующий() = -1 Цикл
Док = Выборка.РеализацияТоваров;
Сообщить(Док);
КонецЦикла;
Категория:
COM-объекты, WMI, WSH Выбор запросом элементов справочника и Загрузка в Документ Код 1C v 7.x Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса =
"//{{ЗАПРОС(Сформировать)
//|Период с ВыбНачПериода по ВыбКонПериода;
|Обрабатывать НеПомеченныеНаУдаление;
|Номенклатура = Справочник.Номенклатура.ТекущийЭлемент;
|Группировка Номенклатура без групп;
|Условие(ПустоеЗначение(СокрЛП(Номенклатура.Наименование))=0);
|Условие(Номенклатура.ПометкаУдаления()=0);
|"//}}ЗАПРОС
;
// Если ошибка в запросе, то выход из процедуры
Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
Возврат;
КонецЕсли;
Запрос.Выгрузить(ТЗ,0,0);
Док = СоздатьОбъект("Документ");
Док.НайтиДокумент(ВыбИнвентаризацияТМЦ);
Док.ЗагрузитьТабличнуюЧасть(ТЗ);
Док.Записать();
Категория:
Документы Значение параметра Extended Properties для разных версий MS Excel Параметр
Extended Properties=""Excel 8.0;" обозначает версию в котором сохранен файл
* 1997 год — Excel 97(8) — Microsoft Office 97
* 1999 год — Excel 2000 (9) — Microsoft Office 2000
* 2001 год — Excel 2002 (10) — Microsoft Office XP
* 2003 год — Excel 2003 (11) — Microsoft Office 2003
* 2007 год — Excel 2007 (12) — Microsoft Office 2007
* 2010 год — Excel 2010 (13) — Microsoft Office 2010
Примеры
Код 1C v 8.х //подключение
Conn= Новый COMОбъект("ADODB.Connection");
Conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+Параметры.ИмяФайла+";
|Extended Properties=""Excel 8.0;"+?(Параметры.ЗаголовкиКолонокИменаСтолбцовExcel,"HDR=NO;","")+"IMEX=1;""";
//Conn.ConnectionTimeout=0;
//Conn.CursorLocation=3;
Conn.Open();
//************Текст запроса
ТекстЗапроса="S_elect
| *
|FROM [Лист1$]
// |INNER JOIN
// | ON
// |WHERE
// |GROUP BY
// | ORDER BY
|";
Результат=Conn.Execute(ТекстЗапроса);
Ссылки по теме:
V8 1С8.1 и Excel 2007 Категория:
Работа с Microsoft Office и OpenOffice Поиск в базе битых ссылок - "объект не найден" В статье
Битая ссылка, <Объект не найден>, Уникальный Идентификатор, GUID мы обсуждали как востановить битые ссылки!
А вот как найти в базе все битые ссылки, которые имеют вид типа "<Объект не найден> (137:8b270030482898d011daad3cc45fc830)"?
Для поиска этого была написана данная обработка:
Скачивать файлы может только зарегистрированный пользователь!
Для поиска: Выбираем объекты метаданных , которые хотим проверить, жмем кнопочку "Выполнить" и наблюдаем в таблице выходные данные. Откуда можем попасть в объекты-источники.
Для программиста:
Код 1C v 8.х Процедура КнопкаВыполнитьНажатие(Кнопка)
ИспользоватьОграничение = ЗначениеЗаполнено(ОграничениеТипов);
РезультатПоиска.Очистить();
Для Каждого ОбъектыМетаданных Из КоллекцияОбъектов Цикл
Для Каждого ОбъектМетаданных Из ОбъектыМетаданных Цикл
Состояние(ОбъектМетаданных.ПолноеИмя());
ПроверитьОбъектНаБитыеСсылки(ОбъектМетаданных);
КонецЦикла;
КонецЦикла;
Для Каждого ОбъектыМетаданных Из КоллекцияРегистров Цикл
Для Каждого ОбъектМетаданных Из ОбъектыМетаданных Цикл
Состояние(ОбъектМетаданных.ПолноеИмя());
ПроверитьРегистрНаБитыеСсылки(ОбъектМетаданных);
КонецЦикла;
КонецЦикла;
//Анализ последовательностей
//ПроверитьОбъектНаБитыеСсылки(Метаданные.Справочники.СотрудникиОрганизаций);
КонецПроцедуры
Процедура ВывестиДанные(ТекстЗапроса)
Запрос = Новый Запрос(ТекстЗапроса);
Попытка
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
ТЗ = РезультатЗапроса.Выгрузить();
Для Каждого Стр Из ТЗ Цикл
ОбработкаПрерыванияПользователя();
Строка = РезультатПоиска.Добавить();
ЗаполнитьЗначенияСвойств(Строка, Стр);
КонецЦикла;
КонецЕсли;
Исключение
Сообщить(ИнформацияОбОшибке().Описание + " " + ИнформацияОбОшибке().Причина);
КонецПопытки;
КонецПроцедуры
Процедура ПроверитьРегистрНаБитыеСсылки(ОбъектМетаданных)
ИмяТаблицы = ОбъектМетаданных.ПолноеИмя();
Если Метаданные.РегистрыСведений.Содержит(ОбъектМетаданных) Тогда
Если ОбъектМетаданных.РежимЗаписи = НезависимыйРежимЗаписи Тогда
//АнализСвойствРегистраСведений(ОбъектМетаданных, ОбъектМетаданных.Измерения, ИмяТаблицы);
//АнализСвойствРегистраСведений(ОбъектМетаданных, ОбъектМетаданных.Ресурсы, ИмяТаблицы);
//АнализСвойствРегистраСведений(ОбъектМетаданных, ОбъектМетаданных.Реквизиты, ИмяТаблицы);
Возврат;
КонецЕсли;
АнализСвойствРегистра(ОбъектМетаданных, ОбъектМетаданных.Реквизиты, ИмяТаблицы);
КонецЕсли;
АнализСвойствРегистра(ОбъектМетаданных, ОбъектМетаданных.Измерения, ИмяТаблицы);
АнализСвойствРегистра(ОбъектМетаданных, ОбъектМетаданных.Реквизиты, ИмяТаблицы);
АнализРегистратораРегистра(ОбъектМетаданных, ИмяТаблицы);
Если Метаданные.РегистрыБухгалтерии.Содержит(ОбъектМетаданных) Тогда
//Для рег. бухгалтерии анализ субконто
КонецЕсли;
Если Метаданные.РегистрыРасчета.Содержит(ОбъектМетаданных) Тогда
//Для регистров расчета доп. анализ
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьОбъектНаБитыеСсылки(ОбъектМетаданных)
ИмяТаблицы = ОбъектМетаданных.ПолноеИмя();
АнализСвойствОбъекта(ОбъектМетаданных, ОбъектМетаданных.Реквизиты, ИмяТаблицы);
Для Каждого ТабЧасть Из ОбъектМетаданных.ТабличныеЧасти Цикл
Если ТабличныеЧастиИсключения.Найти(ТабЧасть.Имя) <> Неопределено Тогда
Продолжить;
КонецЕсли;
АнализСвойствОбъекта(ОбъектМетаданных, ТабЧасть.Реквизиты, ИмяТаблицы + "." + ТабЧасть.Имя)
КонецЦикла;
//проверка владельца у справочников
Если Метаданные.Справочники.Содержит(ОбъектМетаданных) И ОбъектМетаданных.Владельцы.Количество() > 0 Тогда
МассивВладельцев = Новый Массив;
Для Каждого Элемент Из ОбъектМетаданных.Владельцы Цикл
МассивВладельцев.Добавить(Элемент);
КонецЦикла;
//АнализСвойствВладельцаОбъекта(ОбъектМетаданных, МассивВладельцев, ИмяТаблицы);
КонецЕсли;
//Для задач поле исполнитель
//проверки в журналах
ОбработкаПрерыванияПользователя();
КонецПроцедуры
Процедура АнализСвойствОбъекта(ОбъектМетаданных, Свойства, ИмяТаблицы)
Для Каждого Реквизит Из Свойства Цикл
Если РеквизитыИсключения.Найти(Реквизит.Имя) <> Неопределено Тогда
Продолжить;
КонецЕсли;
Для Каждого моТип Из Реквизит.Тип.Типы() Цикл
ТекстЗапроса = "";
МетаданныеТипа = Метаданные.НайтиПоТипу(моТип);
Если МетаданныеТипа <> Неопределено
И Не Метаданные.Перечисления.Содержит(МетаданныеТипа) Тогда
Если ИспользоватьОграничение Тогда
Если Не ПоискПоТипу(МетаданныеТипа.ПолноеИмя()) Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
ДобавитьВЗапросОбъект(ТекстЗапроса, ОбъектМетаданных, ИмяТаблицы, Реквизит.Имя, моТип);
КонецЕсли;
Если Не ПустаяСтрока(ТекстЗапроса) Тогда
ВывестиДанные(ТекстЗапроса);
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура АнализСвойствРегистра(ОбъектМетаданных, Свойства, ИмяТаблицы)
Для Каждого Реквизит Из Свойства Цикл
Если РеквизитыИсключения.Найти(Реквизит.Имя) <> Неопределено Тогда
Продолжить;
КонецЕсли;
Для Каждого моТип Из Реквизит.Тип.Типы() Цикл
ТекстЗапроса = "";
МетаданныеТипа = Метаданные.НайтиПоТипу(моТип);
Если МетаданныеТипа <> Неопределено
И Не Метаданные.Перечисления.Содержит(МетаданныеТипа) Тогда
Если ИспользоватьОграничение Тогда
Если Не ПоискПоТипу(МетаданныеТипа.ПолноеИмя()) Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
ДобавитьВЗапросРегистр(ТекстЗапроса, ОбъектМетаданных, ИмяТаблицы, Реквизит.Имя, моТип);
КонецЕсли;
Если Не ПустаяСтрока(ТекстЗапроса) Тогда
ВывестиДанные(ТекстЗапроса);
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура АнализРегистратораРегистра(ОбъектМетаданных, ИмяТаблицы)
МассивРегистраторов = ПолучитьСписокРегистраторов(ОбъектМетаданных);
Для Каждого Регистратор Из МассивРегистраторов Цикл
Если РеквизитыИсключения.Найти("Регистратор") <> Неопределено Тогда
Продолжить;
КонецЕсли;
моТип = Регистратор;
ТекстЗапроса = "";
МетаданныеТипа = Метаданные.НайтиПоТипу(моТип);
Если МетаданныеТипа <> Неопределено
И Не Метаданные.Перечисления.Содержит(МетаданныеТипа) Тогда
Если ИспользоватьОграничение Тогда
Если Не ПоискПоТипу(МетаданныеТипа.ПолноеИмя()) Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
ДобавитьВЗапросРегистр(ТекстЗапроса, ОбъектМетаданных, ИмяТаблицы, "Регистратор", моТип);
КонецЕсли;
Если Не ПустаяСтрока(ТекстЗапроса) Тогда
ВывестиДанные(ТекстЗапроса);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ПолучитьСписокРегистраторов(ОбъектМетаданных)
МассивРегистраторов = Новый Массив;
МенеджерОбъект = ПолучитьМенеджерОбъекта(ОбъектМетаданных);
Если МенеджерОбъект <> Неопределено Тогда
НаборЗаписей = МенеджерОбъект.СоздатьНаборЗаписей();
ЭлементОтбора = НаборЗаписей.Отбор.Регистратор;
МассивРегистраторов = ЭлементОтбора.ТипЗначения.Типы();
КонецЕсли;
Возврат МассивРегистраторов;
КонецФункции
Функция ПолучитьМенеджерОбъекта(ОбъектМетаданных)
Перем МенеджерОбъекта;
Если Метаданные.РегистрыБухгалтерии.Содержит(ОбъектМетаданных) Тогда
МенеджерОбъекта = РегистрыБухгалтерии[ОбъектМетаданных.Имя];
ИначеЕсли Метаданные.РегистрыНакопления.Содержит(ОбъектМетаданных) Тогда
МенеджерОбъекта = РегистрыНакопления[ОбъектМетаданных.Имя];
ИначеЕсли Метаданные.РегистрыСведений.Содержит(ОбъектМетаданных) Тогда
МенеджерОбъекта = РегистрыСведений[ОбъектМетаданных.Имя];
ИначеЕсли Метаданные.РегистрыРасчета.Содержит(ОбъектМетаданных) Тогда
МенеджерОбъекта = РегистрыРасчета[ОбъектМетаданных.Имя];
КонецЕсли;
Возврат МенеджерОбъекта;
КонецФункции
Функция ПоискПоТипу(ИмяТипа)
Результат = Ложь;
Если ИспользоватьОграничение Тогда
МассивСтрок = ОграничениеТипов.НайтиСтроки(Новый Структура("ТипДанных", ИмяТипа));
Если ЗначениеЗаполнено(МассивСтрок) Тогда
Результат = Истина;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ДобавитьВЗапросРегистр(ТекстЗапроса, ОбъектМетаданных, ИмяТаблицы, ИмяРеквизита, ТипРеквизита)
Текст = "ВЫБРАТЬ Об." + ИмяРеквизита + " КАК Объект,
| """ + ИмяТаблицы + "." + ИмяРеквизита + """ КАК ТаблицаИсточник,
| Об.Регистратор КАК ОбъектИсточник,
| " + ДобавитьОписаниеТипа(ИмяРеквизита, ТипРеквизита) + "
|ИЗ
| " + ИмяТаблицы + " КАК Об
|ГДЕ " + ДобавитьУсловия(ИмяРеквизита, ТипРеквизита);
ТекстЗапроса = ТекстЗапроса + ?(ПустаяСтрока(ТекстЗапроса), "", Символы.ПС + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС) + Текст;
КонецПроцедуры
Процедура ДобавитьВЗапросОбъект(ТекстЗапроса, ОбъектМетаданных, ИмяТаблицы, ИмяРеквизита, ТипРеквизита)
Текст = "ВЫБРАТЬ Об." + ИмяРеквизита + " КАК Объект,
| """ + ИмяТаблицы + "." + ИмяРеквизита + """ КАК ТаблицаИсточник,
| Об.Ссылка КАК ОбъектИсточник,
| " + ДобавитьОписаниеТипа(ИмяРеквизита, ТипРеквизита) + "
|ИЗ
| " + ИмяТаблицы + " КАК Об
|ГДЕ " + ДобавитьУсловия(ИмяРеквизита, ТипРеквизита);
ТекстЗапроса = ТекстЗапроса + ?(ПустаяСтрока(ТекстЗапроса), "", Символы.ПС + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС) + Текст;
КонецПроцедуры
Функция ДобавитьУсловия(ИмяРеквизита, ТипРеквизита)
мдОбъекта = Метаданные.НайтиПоТипу(ТипРеквизита);
ИмяТаблицы = мдОбъекта.ПолноеИмя();
ПроверкаНаПустыеЗначения = " Об." + ИмяРеквизита + " ССЫЛКА " + ИмяТаблицы;
ПроверкаНаПустыеЗначения = ПроверкаНаПустыеЗначения + " И ВЫРАЗИТЬ(Об." + ИмяРеквизита + " КАК " + ИмяТаблицы + ").Ссылка есть null";
Если Не Метаданные.Перечисления.Содержит(мдОбъекта) Тогда
ПроверкаНаПустыеЗначения = ПроверкаНаПустыеЗначения + " И Об." + ИмяРеквизита + " <> Значение(" + ИмяТаблицы + ".ПустаяСсылка)";
КонецЕсли;
Возврат ПроверкаНаПустыеЗначения;
КонецФункции
Функция ДобавитьОписаниеТипа(ИмяРеквизита, ТипРеквизита)
ОбъектТипа = Метаданные.НайтиПоТипу(ТипРеквизита);
ИмяТаблицы = ОбъектТипа.ПолноеИмя();
ОписаниеТипа = """" + ИмяТаблицы + """ КАК ТипДанных";
Возврат ОписаниеТипа;
КонецФункции
Процедура ОграничениеТиповТипДанныхНачалоВыбора(Элемент, СтандартнаяОбработка)
Перем ЭлементСписка;
СтандартнаяОбработка = Ложь;
Строка = ЭлементыФормы.ОграничениеТипов.ТекущиеДанные;
Если Не ПустаяСтрока(Строка.ТипДанных) Тогда
ЭлементСписка = СписокТипов.НайтиПоЗначению(Строка.ТипДанных);
КонецЕсли;
ВыбранныйЭлемент = СписокТипов.ВыбратьЭлемент( , ЭлементСписка);
Если ВыбранныйЭлемент <> Неопределено Тогда
Строка.ТипДанных = ВыбранныйЭлемент.Значение;
КонецЕсли;
КонецПроцедуры
РеквизитыИсключения = Новый Массив;
ТабличныеЧастиИсключения = Новый Массив;
СписокТипов = Новый СписокЗначений;
Для Каждого ОбъектМетаданных Из Метаданные.Справочники Цикл
СписокТипов.Добавить(ОбъектМетаданных.ПолноеИмя(), ОбъектМетаданных.Имя, , БиблиотекаКартинок.СправочникОбъект);
КонецЦикла;
Для Каждого ОбъектМетаданных Из Метаданные.Документы Цикл
СписокТипов.Добавить(ОбъектМетаданных.ПолноеИмя(), ОбъектМетаданных.Имя, , БиблиотекаКартинок.ДокументОбъект);
КонецЦикла;
КоллекцияОбъектов = Новый Массив;
КоллекцияОбъектов.Добавить(Метаданные.ПланыОбмена);
КоллекцияОбъектов.Добавить(Метаданные.Справочники);
КоллекцияОбъектов.Добавить(Метаданные.Документы);
КоллекцияОбъектов.Добавить(Метаданные.ПланыВидовХарактеристик);
КоллекцияОбъектов.Добавить(Метаданные.ПланыСчетов);
КоллекцияОбъектов.Добавить(Метаданные.ПланыВидовРасчета);
КоллекцияОбъектов.Добавить(Метаданные.БизнесПроцессы);
КоллекцияОбъектов.Добавить(Метаданные.Задачи);
КоллекцияРегистров = Новый Массив;
КоллекцияРегистров.Добавить(Метаданные.РегистрыСведений);
КоллекцияРегистров.Добавить(Метаданные.РегистрыНакопления);
КоллекцияРегистров.Добавить(Метаданные.РегистрыБухгалтерии);
КоллекцияРегистров.Добавить(Метаданные.РегистрыРасчета);
Категория:
1С Общие вопросы - Обычные формы Прямые запросы к SQL серверу. Как то возникла ситуация, когда в справочник, с включенной проверкой на уникальность кода, из вне приходят элементы с такими же кодами. Отключать проверку нельзя. Пришлось делать затычку.
Подключение к SQL в общем то широко описано:
Код 1C v 8.х Функция Подключение(Сервер,БД)
cnn = Новый COMОбъект("ADODB.Connection");
cnn.ConnectionTimeOut = 0;
cnn.CommandTimeOut = 0;
cnn.connectionString = "SERVER="+Сервер+"; Database="+БД+"; DRIVER=SQL Server; UID=sa; PWD=*****;";
cnn.Open();
if cnn.State()=0 then
Сообщить("Не удалось соединиться с сервером");
cnn = 0;
Возврат Ложь;
endif;
cnn.Execute("SET NOCOUNT ON");
Возврат cnn;
КонецФункции
Сервер и БД можно получить и программно, но муторно. Эти данные можно взять из свойств БД на сервере 1С.
Название таблицы и полей в SQL можно получить с помощью команды 1С:
Цитата Глобальный контекст
ПолучитьСтруктуруХраненияБазыДанных (GetDBStorageStructureInfo)
Синтаксис:
ПолучитьСтруктуруХраненияБазыДанных(<Объекты метаданных>, <Имена базы данных>)
Параметры:
<Объекты метаданных> (необязательный)
Тип: Массив. Массив имен объектов метаданных или массив объектов метаданных, для которых требуется получить структуру таблиц базы данных.
<Имена базы данных> (необязательный)
Тип: Булево. Определяет, в каких терминах выдается информация о структуре хранения.
Истина - в терминах СУБД
Ложь - в терминах SDBL.
Значение по умолчанию: Ложь
Возвращаемое значение:
Тип: ТаблицаЗначений. Возвращает таблицу значений с описаниями структуры таблиц, индексов и полей базы данных в терминах SDBL или используемой СУБД, в зависимости от значения параметра "Имена базы данных".
Если параметр не используется, то возвращаемая таблица значений содержит информацию о структуре таблиц базы данных всех объектов метаданных.
Таблица значений включает следующие колонки:
ИмяТаблицыХранения(StorageTableName) – имя таблицы SDBL или базы данных;
ИмяТаблицы(TableName) – имя таблицы в терминах языка запросов (для тех у кого оно есть);
Метаданные(Metadata) – полное имя объекта метаданных;
...
Дальше нам нужно новый элемент справочника все ж таки записать, ну например :
Код 1C v 8.х
Попытка
спр.Записать();
Исключение
Сообщить("Не уникальный код "+стр.Код+" у элемента "+стр.Наименование);
Спр.УстановитьНовыйКод();
Спр.Записать();
КонецПопытки;
Все, делаем подмену.
Код 1C v 8.х подключение=Подключение(Сервер,База);
ТекстЗапроса="UPDATE Номенклатура
|SET Номенклатура._Code="+Формат(КодНужный,"ЧГ=0")+"
|FROM _Reference57 AS Номенклатура
|WHERE (CAST(Номенклатура._Folder AS int)=1)
|AND (Номенклатура._Code="+Формат(Спр.Код,"ЧГ=0")+")
|";
подключение.Execute(ТекстЗапроса);
Сообщить("Код "+КодБыл+" подменен на "+КодНужный);
Категория:
Запросы