Программное добавление полей и ресурсов в СКД

Программное добавление полей и ресурсов в СКД

В данном примере будет показано, как осуществить программное добавление полей и ресурсов в СКД отчет, а так же, как передать таблицу значений в качества источника данных. Для примера реализации программного добавления полей в систему компоновки данных, будет использоваться таблица значений с неизвестным количеством колонок, которые нужно вывести в отчет СКД.
Для начала необходимо создать внешний отчет, в модуле объекта которого добавить процедуру ПриКомпоновкеРезультата:

1С программное добавление полей и ресурсов в СКД - СозданиеОтчета

1С программное добавление полей и ресурсов в СКД — СозданиеОтчета


В указанную процедуру добавим следующий код, в комментариях, описаны основные действия, сначала создается таблица значений со случайным количеством колонок, далее колонки, поля, ресурсы, программно добавляются в систему компоновки данными и передаются как внешний набор данных:

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	
	//Структура внешних данных, для передачи в СКД
	ВнешниеНаборыДанных = Новый Структура; 
	
	тзДанные = Новый ТаблицаЗначений;
	
	тзДанные.Колонки.Добавить("Наименование", Новый ОписаниеТипов("Строка"));
	тзДанные.Колонки.Добавить("УникальноеНаименование", Новый ОписаниеТипов("Строка"));
	
	//С помощью генератора случайных чисел определяем количество колонок
	ГенераторСлучайныхЧисел = Новый ГенераторСлучайныхЧисел();
	
	СлучайноеЧисло = ГенераторСлучайныхЧисел.СлучайноеЧисло(1, 10);
	
	//Формируем колонки
	Для Индекс = 1 По СлучайноеЧисло Цикл
		тзДанные.Колонки.Добавить("Колонка" + Индекс, Новый ОписаниеТипов("Число"));
	КонецЦикла; 
	
	//Заполняем таблицу значений данными
	Для Индекс = 1 По 10 Цикл
		
		СтрокаТз = тзДанные.Добавить();
		
		СтрокаТз.Наименование			= "Начальная группировка";
		СтрокаТз.УникальноеНаименование = Новый УникальныйИдентификатор;
		
		Для Счетчик = 1 По СлучайноеЧисло Цикл
			
			ИмяКолонки = "Колонка" + Счетчик;
			СтрокаТз[ИмяКолонки] = ГенераторСлучайныхЧисел.СлучайноеЧисло(1, 10); 
			
		КонецЦикла; 
		
	КонецЦикла; 
	
	//Сохраняем таблицу значений в наборе внешних данных
	ВнешниеНаборыДанных.Вставить("тзДанные", тзДанные);
		
	//Получаем схему из макета
	СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
	
	//Из схемы возьмем настройки
	Настройки = КомпоновщикНастроек.ПолучитьНастройки();
	
	//Программно добавляем поля и ресурсы
	Для Индекс = 1 По СлучайноеЧисло Цикл
		
		Поле = СхемаКомпоновкиДанных.НаборыДанных.НаборДанных1.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
		
		Поле.Заголовок		= "Колонка" + Индекс;
		Поле.ПутьКДанным	= "Колонка" + Индекс;
		Поле.Поле			= "Колонка" + Индекс;
		Поле.ТипЗначения	= Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(15, 2)); 
		
		ПолеРесурса = СхемаКомпоновкиДанных.ПоляИтога.Добавить(); 
		
		ПолеРесурса.Выражение	= "СУММА(Колонка" +  Индекс + ")"; 
		ПолеРесурса.ПутьКДанным	= "Колонка" + Индекс; 
	
		ПолеРесурса.Группировки.Добавить("Наименование"); 
		ПолеРесурса.Группировки.Добавить("УникальноеНаименование"); 
		ПолеРесурса.Группировки.Добавить("ОбщийИтог"); 
		
	КонецЦикла;
	
	//Добавляем в выбранные поля
	Для Индекс = 1 По СлучайноеЧисло Цикл
		
		ВыбранноеПоле = Настройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
		
		ВыбранноеПоле.Заголовок		= "Колонка" + Индекс;
		ВыбранноеПоле.Использование	= Истина; 
		ВыбранноеПоле.Поле			= Новый ПолеКомпоновкиДанных("Колонка" + Индекс); 
		
	КонецЦикла;
	
	//Помещаем в переменную данные о расшифровке данных
	ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
	
	//Формируем макет, с помощью компоновщика макета
	КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
	
	//Передаем в макет компоновки схему, настройки и данные расшифровки
	МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
	
	//Выполним компоновку с помощью процессора компоновки
	ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
	//Передаем внешний набор данных
	ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки);
	
	//Очищаем поле табличного документа
	ДокументРезультат.Очистить();
	
	//Выводим результат в табличный документ
	ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
	ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
	
	ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);

КонецПроцедуры

После необходимо создать основную схему компоновки данных, как показано на изображении:

1С программное добавление полей и ресурсов в СКД - ВнешнийНаборДанных

1С программное добавление полей и ресурсов в СКД — ВнешнийНаборДанных


С простой настройкой группировки:
1С программное добавление полей и ресурсов в СКД - НастройкаГруппировки

1С программное добавление полей и ресурсов в СКД — НастройкаГруппировки


Сохранить внешний отчет и запустить в режиме 1С:Предприятие, несколько раз сформировать отчет, благодаря генератору случайных чисел, количество колонок практически всегда будет разным:
1С программное добавление полей и ресурсов в СКД - Итог

1С программное добавление полей и ресурсов в СКД — Итог


Тем самым было продемонстрировано, как программно добавить поле в систему компоновки данных.

Скачать рассмотренный в статье пример: ПрограммноеДобавлениеПолей

Интеграция 1С и Active Directory

Интеграция 1С и Active Directory

Изредка, в работе программистов и системных администраторов, возникают ситуации и задачи, когда необходимо произвести интеграцию 1С и Active Directory. В данном примере будет показано как с помощью технологии LDAP (англ. Lightweight Directory Access Protocol — «облегчённый протокол доступа к каталогам») и средств интеграции 1С, получить данные из Active Directory. Интеграция 1С и Active Directory может использоваться не только для получения данных, но и для создания объектов в структуре соответствующего домена.
В процессе создания алгоритма интеграции 1С и Active Directory, будет весьма полезна программа «Active Directory Explorer», создателем который является известный программист и писатель Марк Русси́нович. Данная программа позволит вам просмотреть дерево объектов выбранного вами домена, а если в начале запуска программы, сразу нажать кнопку «ОК», то домена по умолчанию, для текущего компьютера.

Active Directory Explorer Интеграция 1С и Active Directory

Интеграция 1С и Active Directory


Далее приведен код процедуры, с помощью которого можно получить список групп домена, в определенном организационном блоке (OU):

&НаКлиенте
Процедура ПолучитьГруппыДомена()
	
	КомандаАДО    = Новый COMОбъект("ADODB.Command");
	СоединениеАДО = Новый COMОбъект("ADODB.Connection");
	
	СоединениеАДО.Provider = "ADSDSOObject";
	Попытка
		СоединениеАДО.Open("Active Directory Provider");	
	Исключение
		Сообщить("Ошибка при открытии Active Directory Provider: " + ОписаниеОшибки());
		Возврат;
	КонецПопытки;
	
	КомандаАДО.ActiveConnection = СоединениеАДО;
	
	//Получаем имя домена к которому принадлежит данный компьютер 
	Попытка
		RootDSE = ПолучитьCOMОбъект("LDAP://RootDSE");
	Исключение
		Сообщить("Ошибка ПолучитьCOMОбъект(LDAP://RootDSE): " + ОписаниеОшибки());
		Возврат;
	КонецПопытки;
	
	ТекущийДомен = RootDSE.Get("defaultNamingContext");
	Сообщить("ТекущийДомен: " + ТекущийДомен);
	
	//Подключаемся к текущему домену
	Попытка
		ОбъектТекущегоДомена = ПолучитьCOMОбъект("LDAP://" + ТекущийДомен);	
	Исключение
		Сообщить("Ошибка ПолучитьCOMОбъект "+"LDAP://" + ТекущийДомен+": " + ОписаниеОшибки());
		Возврат;
	КонецПопытки;
	
	ИмяДомена = ОбъектТекущегоДомена.dc;
	Сообщить("ИмяДомена: " + ИмяДомена);
	
	//Формируем команду получения групп из блока Groups
	КомандаАДО.CommandText = "<LDAP://OU=Groups," + ТекущийДомен + ">" + ";(&(objectClass=top)(objectClass=organizationalUnit));name;onelevel";
	КомандаАДО.Properties("Page Size").Value     = 100;
	КомандаАДО.Properties("Timeout").Value       = 30;
	КомандаАДО.Properties("Cache Results").Value = Ложь;
	
	Попытка
		ВыборкаАДО = КомандаАДО.Execute();	
	Исключение
		Сообщить("Ошибка Execute(): " + ОписаниеОшибки());
		Возврат;
	КонецПопытки;
	
	//Выводим список групп
	Пока НЕ ВыборкаАДО.EOF Цикл
		
		Сообщить("Группа домена: " + ВыборкаАДО.Fields("name").Value);
		
		ВыборкаАДО.MoveNext();
		
	КонецЦикла;
	
	//Обязательно закрываем соединения и объекты
	ВыборкаАДО.Close();
	СоединениеАДО.Close();
	
КонецПроцедуры

Теперь получаем данные пользователей, которые включены в выбранную группу домена:

&НаКлиенте
Процедура ПолучитьПользователейГруппы()
	
	КомандаАДО    = Новый COMОбъект("ADODB.Command");
	СоединениеАДО = Новый COMОбъект("ADODB.Connection");
	
	СоединениеАДО.Provider = "ADSDSOObject";
	Попытка
		СоединениеАДО.Open("Active Directory Provider");	
	Исключение
		Сообщить("Ошибка при открытии Active Directory Provider: " + ОписаниеОшибки());
		Возврат;
	КонецПопытки;
	
	КомандаАДО.ActiveConnection = СоединениеАДО;
	
	Попытка
		RootDSE = ПолучитьCOMОбъект("LDAP://RootDSE");
	Исключение
		Сообщить("Ошибка ПолучитьCOMОбъект(LDAP://RootDSE): " + ОписаниеОшибки());
		Возврат;
	КонецПопытки;
	
	ТекущийДомен = RootDSE.Get("defaultNamingContext");
	Сообщить("ТекущийДомен: " + ТекущийДомен);
	
	Попытка
		ОбъектТекущегоДомена = ПолучитьCOMОбъект("LDAP://" + ТекущийДомен);	
	Исключение
		Сообщить("Ошибка ПолучитьCOMОбъект "+"LDAP://" + Объект.ТекущийДомен+": " + ОписаниеОшибки());
		Возврат;
	КонецПопытки;
	
	ИмяДомена = ОбъектТекущегоДомена.dc;
	Сообщить("ИмяДомена: " + ИмяДомена);
	
	
	КомандаАДО.CommandText = "<LDAP://OU=" + ГруппыДомена + ",OU=Groups," + Объект.ТекущийДомен + ">" + ";(&(objectCategory=person)(objectClass=user));sAMAccountName,userAccountControl,displayName,department,mail,telephoneNumber;onelevel";
	КомандаАДО.Properties("Page Size").Value     = 100;
	КомандаАДО.Properties("Timeout").Value       = 30;
	КомандаАДО.Properties("Cache Results").Value = Ложь;
	
	Попытка
		ВыборкаАДО = КомандаАДО.Execute();	
	Исключение
		Сообщить("Ошибка Execute(): " + ОписаниеОшибки());
		Возврат;
	КонецПопытки;
	
	Пока НЕ ВыборкаАДО.EOF Цикл
		
		ПользовательДомена = Новый Структура;
		
		Если ВыборкаАДО.Fields("userAccountControl").Value = 514 ИЛИ
			ВыборкаАДО.Fields("userAccountControl").Value = 546 ИЛИ
			ВыборкаАДО.Fields("userAccountControl").Value = 66050 Тогда
			 
			Сообщить("Заблокирован");
		Иначе
			Сообщить("НеЗаблокирован");
		КонецЕсли;
		
		Сообщить("ИмяПользователя " + СокрЛП(ВыборкаАДО.Fields("displayName").Value));
		Сообщить("ИмяАккаунта "     + СокрЛП(ВыборкаАДО.Fields("sAMAccountName").Value));
		Сообщить("Подразделение "   + СокрЛП(ВыборкаАДО.Fields("department").Value));
		Сообщить("Почта "           + СокрЛП(ВыборкаАДО.Fields("mail").Value));
		Сообщить("Телефон "         + СокрЛП(ВыборкаАДО.Fields("telephoneNumber").Value));
		
		ВыборкаАДО.MoveNext();
		
	КонецЦикла;
	
	ВыборкаАДО.Close();
	СоединениеАДО.Close();
	
КонецПроцедуры

По этому примеру можно создавать более сложные примеры интеграции 1С и Active Directory, более подробные сведения, вы можете получить по следующим адресам:
ADSI LDAP Provider
Использование протокола LDAP в скриптах

1с word шаблон — Заполнение таблиц в шаблоне Word

1с word шаблон — Заполнение таблиц в шаблоне Word

В предыдущей заметке «Использование шаблонов Word в 1С» был показан простой способ, как используя механизмы 1С и документа Word в качестве шаблона, можно создать печатную форму для вывода данных. В текущей заметке «1с word шаблон» будет показан один из способов, как можно реализовать заполнение таблиц в шаблоне Word.

Для примера использовался шаблон Word следующего вида:

1с word шаблон - Заполнение таблиц в шаблоне Word - Шаблон

1с word шаблон — Заполнение таблиц в шаблоне Word — Шаблон


Как видно из шаблона, закладка «Таблица1» является указателем на начало таблицы и служит для позиционирования выделения.
Теперь непосредственно сам способ, для его реализации использовалась внешняя обработка, в модуле формы которой, описана лишь одна процедура «ПриОткрытии(Отказ)»:

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	//Попытка создать COM объект
	Попытка
		ОбъектВорд = Новый COMОбъект("Word.Application"); 
	Исключение
		Сообщить("Ошибка при запуске Microsoft Word: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
	КонецПопытки;
	
	//Путь к шаблону
	ОбъектВорд.Documents.Add("C:\Users\Константин\Desktop\Шаблон.docx");
	ШаблонВорд = ОбъектВорд.ActiveDocument;
	
	//Заполняем первую таблицу
	Если ШаблонВорд.Bookmarks.Exists("Таблица1") Тогда
		
		//Выделяем обязательную закладку начала таблицы
		ШаблонВорд.Bookmarks("Таблица1").Select();
		
		
		//Перемещаемся вниз, выделяем строку таблицы и копируем ее в буфер обмена
		ШаблонВорд.Application.Selection.MoveDown();
		ШаблонВорд.Application.Selection.SelectRow();
		ШаблонВорд.Application.Selection.Copy();
		
		Для Счетчик = 1 По 10 Цикл
			
			//Заменяем значения
			ШаблонВорд.Application.Selection.Find.Execute("Номер" ,,,,,,,,,Счетчик,2);
			ШаблонВорд.Application.Selection.Find.Execute("ЗначениеКолонки1" ,,,,,,,,,Счетчик+10,2);
			//Последний параметр поиска пустой
			ШаблонВорд.Application.Selection.Find.Execute("ЗначениеКолонки2" ,,,,,,,,,Счетчик+100,);
			
			//Перемещаемся вниз, вставляем из буфера обмена строку
			ШаблонВорд.Application.Selection.MoveDown();
			ШаблонВорд.Application.Selection.Paste();
			//Перемещаемся вверх и выделяем строку для замены значений
			ШаблонВорд.Application.Selection.MoveUp();
			ШаблонВорд.Application.Selection.SelectRow();
			
		КонецЦикла;
		
		//Вырезаем лишнюю строку
		ШаблонВорд.Application.Selection.Cut();
		
		//Скрываем обязательную закладку начала таблицы
		ШаблонВорд.Bookmarks("Таблица1").Select();
		ШаблонВорд.Application.Selection.TypeText(" ");
		
	КонецЕсли;
	
	ОбъектВорд.Application.Visible = Истина;
	ОбъектВорд.Activate();
	
	//Закрытие документа
	//ОбъектВорд.Application.Quit();
	
КонецПроцедуры

Как видно из кода процедуры, сначала находим закладку, выделяем и копируем строку таблицы находящуюся ниже, после заменяем текст на значения и вставляем скопированную строку. Результат работы внешней обработки 1С «Заполнение таблиц в шаблоне Word»:

1с word шаблон - Заполнение таблиц в шаблоне Word - Результат

1с word шаблон — Заполнение таблиц в шаблоне Word — Результат

Скачать файл обработки 1С и шаблона Word.

Загрузка из Excel в 1С

Загрузка из Excel в 1С

Загрузка из Excel в 1С, довольно частая задача, которую приходится решать программистам 1С. В данной заметке будет показано, как произвести загрузку данных из файла Excel в 1С, наиболее быстрым и оптимальным способом. Перед тем как показать примеры кода, объяснюю как производить отладку и проверку выполнения SQL запросов к файлу Excel, для последующей загрузки данных в программу 1С.

Для примера будет использоваться файл формата Excel со следующей структурой и данными:

Загрузка из Эксель в 1С. SQL запрос к файлу Excel. Загрузка из Excel с помощью запроса SQL в 1С.

Данные Excel для загрузки в 1С


Чтобы выполнить SQL запрос к файлу Excel и проверить результат, необходимо запустить программу Microsoft Excel, перейти в главном меню программы на вкладку «Данные», далее нажать кнопку «Из других источников» и в появившемся меню выбрать пункт «Из Microsoft Query»:
Запуск MSQuery для загрузки из Эксель в 1С

Запуск MSQuery для загрузки из Эксель в 1С


После появится окно «Выбор источника данных», в нем необходимо выбрать пункт «Excel Files*» и нажать «ОК»:
Выбор источника для загрузки

Выбор источника для загрузки


Далее выбрать непосредственно ваш файл Excel для выборки данных. Может появится предупреждение, что «Данный источник данных не содержит видимых таблиц», игнорируем его и нажимаем «ОК». После необходимо в параметрах установить пункт отображать системные таблицы:
Выбор системные таблицы

Выбор системные таблицы


После включения данной опции, появится возможность выбора листов из книги Excel и столбцов для запроса:
Выбор столбцы запроса

Выбор столбцы запроса


Дальше необходимо несколько раз нажать «Далее» и на последнем шаге, выбрать пункт «Просмотр или изменение данных в Microsoft Query» и «Готово»:
Просмотр изменение

Просмотр изменение


Откроется окно «Microsoft Query», в котором мы видим выборку данных из нашего файл Excel. Для тестирования и редактирования SQL запросов к файлу Excel, используется кнопка «SQL», при помощи которой вызывается окно редактирования запроса:
Запрос SQL

Запрос SQL


Теперь, когда вы знаете, как тестировать ваши SQL запросы к файлу Excel, попробуем загрузить данные в программу 1С, для этого создадим внешнюю обработку, добавим основную форму, для удобства вывода информации добавим реквизит формы с типом «Табличный документ» и отобразим его на форме. В модуле формы добавим процедуру «ПриОткрытии».
Далее приведен код с поясняющими комментариями:

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	//Указываем путь к файлу Excel
	ФайлExcel = "C:\Users\Константин\Desktop\Данные.xls";
	
	//Создаем объект Файл
	ФайлОстатков = Новый Файл(ФайлExcel);
	
	//Проверка на существование файла
	Если ФайлОстатков.Существует() Тогда
		
		//Формируем строку соединения
		СтрокаСоединения = "Driver={Microsoft Excel Driver (*.xls)};
		|DriverId=790;
		|Dbq="        + ФайлОстатков.ПолноеИмя + ";
		|DefaultDir=" + ФайлОстатков.Путь + ";"; 
		
		//Создаем СОМ объект ADODB.Connection
		Соединение = Новый COMОбъект("ADODB.Connection"); 
		Попытка
			//Пробуем подключится к файлу Excel
			Соединение.Open(СтрокаСоединения);           
		Исключение
			Сообщить("Ошибка соединения ADODB.Connection: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
			Возврат;	
		КонецПопытки;
		
		//Пробуем получить имена колонок из файла Excel
		//В случае возникновении ошибки: Попробуйте написать: "SELECT * FROM "[Лист1$A1:IV]" или "SELECT * FROM `Sheet1$A1:IV`"
		ТекстЗапросаSQL = "SELECT * FROM `Лист1$A1:IV`";
		Попытка
			НаборЗаписей = Соединение.Execute(ТекстЗапросаSQL);
		Исключение
			Сообщить("Ошибка соединения ADODB.Recordset: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
			Возврат;	
		КонецПопытки;
		
		//Проверяем количество полученных полей
		Если НаборЗаписей.Fields.Count > 0 Тогда
			
			//Выводим полученные имена колонок
			СтрокДляВывода = "";
			Для каждого СтрокаИзНабора Из НаборЗаписей.Fields Цикл
				СтрокДляВывода = СтрокДляВывода + СтрокаИзНабора.Name + Символы.Таб;
			КонецЦикла;
			
			ВыводСообщений.ДобавитьСтроку(СтрокДляВывода);
			
			//Пробуем получить данные из файла Excel
			ТекстЗапросаSQL = "SELECT * FROM `Лист1$A1:BB`";
			Попытка
				НаборЗаписей = Соединение.Execute(ТекстЗапросаSQL);
			Исключение
				Сообщить("Ошибка соединения ADODB.Recordset: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
				Возврат;	
			КонецПопытки;
			
			//Выводим данные на экран
			Пока НЕ НаборЗаписей.EOF Цикл
				
				СтрокДляВывода = "";
				Для каждого СтрокаИзНабора Из НаборЗаписей.Fields Цикл
					СтрокДляВывода = СтрокДляВывода + СтрокаИзНабора.Value + Символы.Таб;
				КонецЦикла;
				
				ВыводСообщений.ДобавитьСтроку(СтрокДляВывода);
				
				//Перемещяем курсор дальше
				НаборЗаписей.MoveNext();
				
			КонецЦикла;
			
		Иначе
			Сообщить("Не найдены наименования колонок!");
		КонецЕсли;
		
		//Закрываем соединение
		Соединение.Close();
		
	Иначе
		Сообщить("Файл: " + ФайлExcel + " не найден!");
	КонецЕсли;
	
КонецПроцедуры

Результат выполнения внешней обработки по загрузке данных из файла Excel в 1С с помощью запроса SQL, показан на изображении:

Результат выполнения загрузки из Excel в 1С

Результат выполнения загрузки из Excel в 1С

Скачать файлы внешней обработки и данных Excel.