Friday, February 22, 2013

1С СКД Проблемы при программной работе с настройкой компоновщика настроек

Сталкиваюсь постоянно с одной и той же ситуацией в работе в СКД, при программном генерации отчетов в управляемых формах, необходимо инициализировать настройки пользователя.
Фактически после прорисовки пользовательских настроек не возможно установить значения, так как при выборе значений дает выбирать базовые типы.

КомпоновщикНастроек.Инициализировать(Отчеты[НазваниеОтчета].ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных"));
КомпоновщикНастроек.ЗагрузитьНастройки(Отчеты[НазваниеОтчета].ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных").ВариантыНастроек[ВаринтНастроек].Настройки);

Не знаю, что думал в 1С, но порывшись в нете нашел правильную схему формирования настроек

АдресСКД = ПоместитьВоВременноеХранилище(Отчеты[НазваниеОтчета].ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных"), ЭтаФорма.УникальныйИдентификатор);
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресСКД);

КомпоновщикНастроек.Инициализировать(ИсточникДоступныхНастроек);
КомпоновщикНастроек.ЗагрузитьНастройки(Отчеты[НазваниеОтчета].ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных").ВариантыНастроек[ВаринтНастроек].Настройки);

Monday, February 11, 2013

Формирование отчета с использованием СКД и внешних наборов данных

Очень странно, но единой схемы в интернете по работе в системе компоновки данных я не нашел и на вылетающие ошибки пришлось потратить время, а так имеем задачу соединить остатки 2 разных баз "Управленческой" и бухгалтерской. Так как синхронизация в базах выполняется регулярно имеем одинаковые уникальные идентификаторы.
Начинаем
1. Создаем внешний отчет



1.1. В "наборы данных" добавляем "Набор данных - объединение"
1.2. В созданный набор добавляем "Набор данных - запрос" И формируем необходимый нам запрос с помощью конструктора.
1.3. В набор объединение добавляем также "Набор данных - объект" и прописываем поля которые будут загружены с таблицызначений, не забываем что поля должны совпадать с полями из набора данных запрос

2. После этого переходим в модуль объекта, и добавляем стандартную процедуру "ПриКомпоновкеРезультата". 1С автоматически генерирует процедуру со всеми входящими параметрами. И начинаем формировать заполнение процедуры



Exported from Notepad++




Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
// При формирование отключаем стандартную обработку, в противном случае постоянно будет выдавать следующую ошибку
// Ошибка исполнения отчета
//по причине:
//Ошибка инициализации
//по причине:
//Ошибка создания набора данных "НаборДанных"
//по причине:
//Не найден внешний набор данных "ТаблОст"

СтандартнаяОбработка = Ложь;


//Формируем подключение к внешней базе 1с
Подкл = Новый COMОбъект("V82.COMConnector");
COMОбъект = Подкл.Connect("Srvr=""mws-01"";Ref=""GlobalBase"";Usr=""*****"";Pwd=""******""");

//Формируем запрос во внешней базе

Запрос = COMОбъект.NewObject("Запрос");

Запрос.Текст = "ВЫБРАТЬ
| ТоварыНаСкладахОстатки.Номенклатура,
| ТоварыНаСкладахОстатки.ВНаличииОстаток КАК КоличествоОстаток,
| ТоварыНаСкладахОстатки.ВРезервеОстаток КАК ВРезерве
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
|ГДЕ
| ТоварыНаСкладахОстатки.Склад В
| (ВЫБРАТЬ
| Склады.Ссылка
| ИЗ
| Справочник.Склады КАК Склады
| ГДЕ
| Склады.Родитель.Наименование = ""Центральные Склады"")"
;



Результат = Запрос.Выполнить();
//Получаем результат и создаем и заполняем таблицу значений в текущей
ТаблОст = Новый ТаблицаЗначений;
ТаблОст.Колонки.Добавить("Номенклатура",новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ТаблОст.Колонки.Добавить("Организация",ОбщегоНазначения.ПолучитьОписаниеТиповСтроки(10));
ТаблОст.Колонки.Добавить("КоличествоОстаток", ОбщегоНазначения.ПолучитьОписаниеТиповЧисла(15,3));
ТаблОст.Колонки.Добавить("СуммаОстаток", ОбщегоНазначения.ПолучитьОписаниеТиповЧисла(15,2));
Табл = Результат.Выгрузить();
Для х=0 по Табл.Количество()-1 Цикл
ЗначСтр = Табл.Получить(х);
НоваяСтрока = ТаблОст.Добавить();
//По уникальному идентификатору получаем значение и преобразуем в ссылку в текущей базе
НоваяСтрока.Номенклатура = Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор(COMОбъект.String(ЗначСтр.Номенклатура.УникальныйИдентификатор())));
НоваяСтрока.Организация = "Упр"; // формируем левое название, так как управленческой базы нет в бухгалтерии
НоваяСтрока.СуммаОстаток = 0;
НоваяСтрока.КоличествоОстаток = Число(ЗначСтр.КоличествоОстаток);
КонецЦикла;
COMОбъект = неопределено;
Подкл = неопределено;


ВнешниеНаборыДанных = Новый Структура;
ВнешниеНаборыДанных.Вставить("ТаблОст",ТаблОст); // Формируем структуру для передечи в СКД


КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

НастройкиКомпоновкиДанных = КомпоновщикНастроек.ПолучитьНастройки();

ТекСхема = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");

МакетКомпоновки = КомпоновщикМакета.Выполнить(
ТекСхема,
НастройкиКомпоновкиДанных,
ДанныеРасшифровки
);

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(
МакетКомпоновки,
ВнешниеНаборыДанных,
ДанныеРасшифровки
);

ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.НачатьВывод();
ПроцессорВывода.Вывести(ПроцессорКомпоновки, Истина);
ПроцессорВывода.ЗакончитьВывод();

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



3. Далее, заполняем настройки, ресурсы и параметры

Как итог получаем отчет с нужными данными





Friday, February 8, 2013

Функция формирования навигационной ссылки для внешнего соединения 1С 8.2 Управляемые формы

У меня возникла ситуация, при рассылки сообщений при изменений статусов документов, через почту, с необходимостью указывать ссылку на документ, так как в работе используем 1С управляемые формы, до хватало ссылки на активацию через браузер, внизу сама функция формирования ссылки:



Exported from Notepad++




Функция ВернутьНавигационнуюСсылку(СсылкаНаОбъект) Экспорт
Возврат "http://ТутУказываетсяАдресСервера/ТутНазваниеБазы/#"+СтрЗаменить(ПолучитьНавигационнуюСсылку(СсылкаНаОбъект),"""","%22");
КонецФункции

Рассылка СКД отчетов из 1С с помощью фоновых заданий.

Интересная схема рассылки отчетов из 1С.
СКД в 1С достаточно мощная и грамотная схема, конечно есть и ошибки и проблемы, но думаю их исправят.
Так вот, раньше что бы сформировать отчет, приходилось достаточно много писать и дорабатывать не только на 1с, но и на других языках.
Сейчас же можно достаточно быстро и эффективно формировать данные самой 1С. На текущий момент, я использую платформу 1С 8.2.17.153.

1. И самое основное для создания рассылки необходимо создать фоновое задание и процедуру формирования рассылки. Для этого я создал общий модуль "ПочтовыеРассылки" и установил в свойствах что он является "Серверным" и свойствах "Вызов сервера=Истина" + "Привилегированный=Истина".
Далее в него добавил 2 процедуры:

С процедурой отправить, думаю все понятно.


Exported from Notepad++



//Требование к запуску процедуры
//1.ДанныеПисьма = Структура
//1.1 ДанныеПисьма.Кому = массив адресат
//1.2 ДанныеПисьма.Вложения = массив строчный на файлы для вложения
//1.3 ДанныеПисьма.Тема - Тема письма
//1.4 Тело
//1.5 ОбратныйАдрес
//ДанныеПисьма = Новый Структура("Тема,Тело,Кому,Вложения");

Процедура Отправить(ДанныеПисьма) экспорт
//для получения доступа к набору свойств для соединения с сервером
//создадим новый объект
УстановитьПривилегированныйРежим(Истина);
Профиль = Новый ИнтернетПочтовыйПрофиль;

//Пропишем параметры соединения
//ip адрес или имя SMTP сервера
Профиль.АдресСервераSMTP = "*********";

//Порт SMTP сервера
Профиль.ПортSMTP = "***";

//Имя пользователя почтового ящика
Профиль.Пользователь = "***********";

//Пароль доступа к почтовому ящику
Профиль.Пароль = "******************";

//При необходимости добавляем аутентификацию
Профиль.АутентификацияSMTP = СпособSMTPАутентификации.БезАутентификации;
//Профиль.ПарольSMTP = Профиль.Пароль;
//Профиль.ПользовательSMTP = Профиль.Пользователь;
// Создаем объект для работы с почтой
Почта = Новый ИнтернетПочта;

//Выполняем подключение, согласно указанный параметров
Попытка
Почта.Подключиться(Профиль);
Исключение
//При подключении возникла ошибка, сообщим
Сообщить("Ошибка при подключении к серверу" + ОписаниеОшибки());
Возврат;
КонецПопытки;

//Создаем новое письмо (сообщение)
Сообщение = Новый ИнтернетПочтовоеСообщение;
Если ДанныеПисьма.Свойство("ОбратныйАдрес") И ТипЗнч(ДанныеПисьма.ОбратныйАдрес)= Тип("Строка") тогда
Сообщение.ОбратныйАдрес.Добавить(ДанныеПисьма.ОбратныйАдрес);
Сообщение.Отправитель = ДанныеПисьма.ОбратныйАдрес;
КонецЕсли;

//Указываем отправителя
//Сообщение.Отправитель = "*********@*****";

Если ТипЗнч(ДанныеПисьма.Кому)= Тип("Строка") тогда
Сообщение.Получатели.Добавить(ДанныеПисьма.Кому);
ИначеЕсли ТипЗнч(ДанныеПисьма.Кому) = Тип("Массив") тогда
Для Каждого ЗначКому из ДанныеПисьма.Кому Цикл
Сообщение.Получатели.Добавить(ЗначКому);
КонецЦикла;
Иначе
//Если какая-то жопа то шлем мне
Сообщение.Получатели.Добавить("********@******");
КонецЕсли;


//Пишем тему письма
Сообщение.Тема = ДанныеПисьма.Тема;

//Формируем текст письма,указываем тип письма
Сообщение.Тексты.Добавить(ДанныеПисьма.Тело,ТипТекстаПочтовогоСообщения.HTML);

//При необходимости делаем вложение с файлом
Если ДанныеПисьма.Свойство("Вложения") тогда
Если ТипЗнч(ДанныеПисьма.Вложения)= Тип("Строка") тогда
Сообщение.Вложения.Добавить(ДанныеПисьма.Вложения);
ИначеЕсли ТипЗнч(ДанныеПисьма.Вложения) = Тип("Массив") тогда
Для Каждого Файл из ДанныеПисьма.Вложения Цикл
Сообщение.Вложения.Добавить(Файл);
КонецЦикла;
КонецЕсли;
КонецЕсли;

//Непосредственно отправка сообщения
Почта.Послать(Сообщение);

//После отправки закрываем соединение
Почта.Отключиться();
Сообщение = Неопределено;
Почта = Неопределено;
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры



// Передаем
//1. СхемаКомпоновкиДанных
//2. КомпоновщикНастроекКомпоновкиДанных
//3. СтрктуруПисьма - см. процедуру Отправить
//4. СтруктуруФайла отправки
//4.1. Файлом = Истина (если доп. вложением) Если ложь то html4 и вставляем в тело письма
//4.2 Типом файла

Процедура СформироватьИОтправитьОтчетПоПочте(СтруктураФормирования) Экспорт

УстановитьПривилегированныйРежим(Истина);
СхемаКомпоновкиДанных=СтруктураФормирования.СхемаКомпоновкиДанных;
//Настройки=СхемаКомпоновкиДанных.НастройкиПоУмолчанию;
//Если СтруктураНастроек=Неопределено тогда
// КомпоновщикНастроекКомпоновкиДанных = СтруктураФормирования.КомпоновщикНастроекКомпоновкиДанных;
//Иначе
// КомпоновщикНастроекКомпоновкиДанных = СтруктураНастроек.КомпоновщикНастроекКомпоновкиДанных;
//КонецЕсли;


КомпоновщикМакета=Новый КомпоновщикМакетаКомпоновкиДанных;
//МакетКомпоновки=КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроекКомпоновкиДанных.Настройки);
МакетКомпоновки=КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, СтруктураФормирования.КомпоновщикНастроекКомпоновкиДанныхНастройки);
ПроцессорКомпоновки=Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
ТабДок=Новый ТабличныйДокумент;
ПроцессорВывода=Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабДок);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);

ТемпФайл=ПолучитьИмяВременногоФайла(Строка(СтруктураФормирования.СтруктураФайла.ТипФайлаТабличногоДокумента));

//ТабДок.Записать(ТемпФайл,ТипФайлаТабличногоДокумента.HTML4);
ТабДок.Записать(ТемпФайл,СтруктураФормирования.СтруктураФайла.ТипФайлаТабличногоДокумента);
Если СтруктураФормирования.СтруктураФайла.Файлом тогда
СтруктураФормирования.СтрктуруПисьма.Вставить("Вложения",ТемпФайл);
Иначе
Текст = Новый ЧтениеТекста(ТемпФайл);
СтруктураФормирования.СтруктураПисьма.Вставить("Тело",Текст.Прочитать());
Текст = Неопределено;
КонецЕсли;

//Требование к запуску процедуры
//1.ДанныеПисьма = Структура
//1.1 ДанныеПисьма.Кому = массив адресат
//1.2 ДанныеПисьма.Вложения = массив строчный на файлы для вложения
//1.3 ДанныеПисьма.Тема - Тема письма
//1.4 Тело
//1.5 ОбратныйАдрес
//ДанныеПисьма = Новый Структура("Тема,Тело,Кому,Вложения");

//Отправить(ДанныеПисьма)

ПочтовыеРассылки.Отправить(СтруктураФормирования.СтруктураПисьма);
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры




А вот вторую процедуру опишу более подробно.
Процедура "СформироватьИОтправитьОтчетПоПочте" получает на входе в структуре следующие значения
1. СхемаКомпоновкиДанных - Схему компоновки данных СКД
2. КомпоновщикНастроекКомпоновкиДанныхНастройки - Настройки схемы компоновки данных, пробывал передавать компоновщик настроек, но по непонятным причинам при выполнении на сервере в структуру вместо компоновщика, передавалась схема. Поигравшись с разными вариантами, стал передавать только настройки, так как сам компоновщик мне и не нужен.
3. СтруктураФайла - в этой структуре я описываю, информацию по вложениям
3.1. СтруктураФайла.ТипФайлаТабличногоДокумента - Передается значение ТипФайлаТабличногоДокумента, если же формируем отчет в теле письма то передаем html4.
3.2. СтруктураФормирования.СтруктураФайла.Файлом - Булево, если значение = Истина, тогда файл передается вложением, если = Ложь - тогда в теле письма.
3.3. СтруктураФормирования.СтруктураПисьма - Передается структура для отправки.

Как итог создаем фоновую задачу для рассылки почты с необходимыми отчетами, в данном случае использую внешнуюю обработку как тестовый вариант, дабы не засорять конфигурацию иногда временными отчетами, как пример - акции для менеджеров.



Exported from Notepad++



Процедура ВыполнитьНаСервереТестовоеСоздание()
Обработка = ВнешниеОтчеты.Создать("c:\Work\UT11\МаркетинговыйОтчет.erf");



СтруктураРаботы = Новый структура;
СхемаКомпоновкиДанных=Обработка.СхемаКомпоновкиДанных;
СтруктураРаботы.Вставить("СхемаКомпоновкиДанных",СхемаКомпоновкиДанных);


КомпоновщикНастроекКомпоновкиДанных = Новый КомпоновщикНастроекКомпоновкиДанных;
//КомпоновщикНастроекКомпоновкиДанных.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));
//КомпоновщикНастроекКомпоновкиДанных.ЗагрузитьНастройки(СхемаКомпоновкиДанных.НастройкиПоУмолчанию);




КомпоновщикНастроекКомпоновкиДанных.ЗагрузитьНастройки(СхемаКомпоновкиДанных.ВариантыНастроек.Основной.Настройки);
КомпоновщикНастроекКомпоновкиДанных.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));



КомпоновщикНастроекКомпоновкиДанных.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("НачалоПериода", НачалоДня(Дата(2013,02,05)));
КомпоновщикНастроекКомпоновкиДанных.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("КонецПериода", КонецДня(Дата(2013,03,29)));
КомпоновщикНастроекКомпоновкиДанных.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Организация", Справочники.Организации.НайтиПоНаименованию("Опт"));
КомпоновщикНастроекКомпоновкиДанных.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("СегментНоменклатурыАкция", Справочники.СегментыНоменклатуры.НайтиПоНаименованию("Акция"));
КомпоновщикНастроекКомпоновкиДанных.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("СегментПартнеровАкция", Справочники.СегментыПартнеров.НайтиПоНаименованию("Рабочие"));



СтруктураРаботы.Вставить("КомпоновщикНастроекКомпоновкиДанных",КомпоновщикНастроекКомпоновкиДанных);

СтруктураФайла = Новый Структура;
СтруктураФайла.Вставить("Файлом",Ложь);
СтруктураФайла.Вставить("ТипФайлаТабличногоДокумента",ТипФайлаТабличногоДокумента.HTML4);
СтруктураРаботы.Вставить("СтруктураФайла",СтруктураФайла);

СтруктураПисьма = Новый Структура;
СтруктураПисьма.Вставить("Кому","*****@*********");
СтруктураПисьма.Вставить("Тема","Акция SOX");
//Новый Структура("Кому,Тема,Тело","********@********","График оплат",СтрHTML)
СтруктураРаботы.Вставить("СтруктураПисьма",СтруктураПисьма);
СтруктураРаботы.Вставить("КомпоновщикНастроекКомпоновкиДанныхНастройки",КомпоновщикНастроекКомпоновкиДанных.Настройки);
//ПочтовыеРассылки.СформироватьИОтправитьОтчетПоПочте(СтруктураРаботы);

Задание = РегламентныеЗадания.СоздатьРегламентноеЗадание(Метаданные.РегламентныеЗадания.ПочтовыеРассылкиОтчетов);
Задание.Использование = Ложь;
Задание.Наименование = "Почтовая рассылка Акция";

ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(СтруктураРаботы);
ПараметрыЗадания.Добавить(Новый Структура("КомпоновщикНастроекКомпоновкиДанных",КомпоновщикНастроекКомпоновкиДанных));
Задание.Параметры = ПараметрыЗадания;

Задание.Записать();



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


После создания фонового задания можно установить регламент, активировать в обработке по работе с фоновыми заданиями.

Monday, February 4, 2013

Формирование планов в Excel по данным из 1С 8.2 УТ11

Поступила от руководства интересная задача по формированию планов.
Фактически данную задачу можно было бы сформировать и в 1С, но манагеры люди гордые им удобнее работать в excel'е. В связи с этим и пришлось хорошенько помучиться, что бы все работало правильно.
Плюс ко всему из-за чего был выбран именно Excel, уточнение в задаче состояло что выбрать для формирования планов нужно было всю номенклатуру с группировкой до 2 уровня.
1. Проблемой которая возникла, использование excel на сервере, так как используем 1С 8.2 (x64) то на сервере в обязательном порядке должен быть установлен офис (x64).
2. Проблема состоит в том что необходимо разрешить использование DCOM, в противном случае не получиться инициализировать Excel.
3. Проблема состоялась в правах на чтение и запись от имени пользователя под которым запущен 1с.
4. Прикол excel необходимо создать каталог (без него excel отказывался записывать файл) c:\Windows\SysWOW64\config\systemprofile\Desktop\
5. C excel'ом пришлось подолбаться хорошо, благо часть задач помогло решить работа с макросами (формируем необходимый файл, после включаем запись макроса, выполняем необходимое действие руками, останавливаем макрос, и входим в него в режиме отладки), но с некоторыми было тяжеловато, пришлось перебирать кучу страниц из поиска в поисках оптимальных идей.

Ниже приведен код работы внешней обработки, основные 2 процедуры ВыгрузитьФайлик и ОформитьПлан.
1. Часть формируем запрос в 1с
2. Для скорости выгружаем данные через OLEDB
3. Открываем в excel и формируем Сводную таблицу (Pivot table)
4. Так как в сводную таблицу очень тяжело что либо вносить, копируем
5. Форматируем в необходимый вид
6. Добавляем две колонки по работе с планами и заполняем иерархию формулами
7. Далее уже от того, что необходимо, либо отсылаем по почте(за комментировано), либо отдаем пользователю


&НаКлиенте Процедура Команда1(Команда) СтруктФункц = Новый Структура(); СтруктФункц.Вставить("Подр", ЭтаФорма.Подразделение); СтруктФункц.Вставить("ПоказыватьСебестоимость", НЕ ЭтаФорма.ПоказыватьСебестоимость); СтруктФункц.Вставить("ДатаНачала",ЭтаФорма.ПериодОтчета.ДатаНачала); СтруктФункц.Вставить("ДатаОкончания",ЭтаФорма.ПериодОтчета.ДатаОкончания); СтруктФункц.Вставить("ФормаУИД",ЭтаФорма.УникальныйИдентификатор); Адрес = ВыгрузитьФайлик(СтруктФункц); ПолучитьФайл(Адрес,Transliterate(Подразделение)+".xlsx",Истина); КонецПроцедуры &НаСервереБезКонтекста Функция ВернутьТекстЗапроса() Возврат "ВЫБРАТЬ | Номенклатура.Ссылка КАК Ссылка, | Номенклатура.НаправленияДеятельности.Наименование КАК НаправленияДеятельности |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Номенклатура.ЭтоГруппа | И Номенклатура.Ссылка В | (ВЫБРАТЬ | КлючиАналитикиУчетаНоменклатуры.Номенклатура.Родитель | ИЗ | РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты(&ПериодНачала, &ПериодОкончания, , ) КАК ВыручкаИСебестоимостьПродажОбороты ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.КлючиАналитикиУчетаНоменклатуры КАК КлючиАналитикиУчетаНоменклатуры | ПО | ВыручкаИСебестоимостьПродажОбороты.АналитикаУчетаНоменклатуры = КлючиАналитикиУчетаНоменклатуры.Ссылка | СГРУППИРОВАТЬ ПО | КлючиАналитикиУчетаНоменклатуры.Номенклатура.Родитель) | |УПОРЯДОЧИТЬ ПО | Номенклатура.Ссылка ИЕРАРХИЯ |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | ВыручкаИСебестоимостьПродажОбороты.Период КАК Период, | КлючиАналитикиУчетаПоПартнерам.Партнер.ОсновнойМенеджер.Наименование КАК Менеджер, | КлючиАналитикиУчетаПоПартнерам.Партнер.ОсновнойМенеджер.ТекущееПодразделение.Наименование + "" ("" + КлючиАналитикиУчетаПоПартнерам.Партнер.ОсновнойМенеджер.ТекущееПодразделение.Код + "")"" КАК Подразделение, | КлючиАналитикиУчетаПоПартнерам.Партнер.Наименование + "" ("" + КлючиАналитикиУчетаПоПартнерам.Партнер.Код + "")"" КАК Партнер, | СУММА(ВыручкаИСебестоимостьПродажОбороты.КоличествоОборот) КАК Количество, | СУММА(ВыручкаИСебестоимостьПродажОбороты.СуммаВыручкиОборот) КАК Выручка, | ВЫБОР | КОГДА &ПоказыватьСебестоимость | ТОГДА 0 | ИНАЧЕ СУММА(ВыручкаИСебестоимостьПродажОбороты.СебестоимостьОборот) | КОНЕЦ КАК Себестоимость, | ВЫБОР | КОГДА &ПоказыватьСебестоимость | ТОГДА 0 | ИНАЧЕ СУММА(ВыручкаИСебестоимостьПродажОбороты.СуммаДополнительныхРасходовОборот) | КОНЕЦ КАК ДопРасходы, | КлючиАналитикиУчетаНоменклатуры.Номенклатура.Родитель КАК Ссылка |ИЗ | РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты( | &ПериодНачала, | &ПериодОкончания, | Месяц, | АналитикаУчетаПоПартнерам В | (ВЫБРАТЬ | КлючиАналитикиУчетаПоПартнерам.Ссылка | ИЗ | Справочник.КлючиАналитикиУчетаПоПартнерам КАК КлючиАналитикиУчетаПоПартнерам | ГДЕ | КлючиАналитикиУчетаПоПартнерам.Организация = &Организация | И КлючиАналитикиУчетаПоПартнерам.Партнер В | (ВЫБРАТЬ | ПартнерыСегмента.Партнер | ИЗ | РегистрСведений.ПартнерыСегмента КАК ПартнерыСегмента ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Партнеры КАК Партнеры ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Пользователи КАК Пользователи | ПО | Партнеры.ОсновнойМенеджер = Пользователи.Ссылка | ПО | ПартнерыСегмента.Партнер = Партнеры.Ссылка | ГДЕ | ПартнерыСегмента.Сегмент = &Сегмент | И НЕ Партнеры.ОсновнойМенеджер = ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка) | И Пользователи.ТекущееПодразделение В | (ВЫБРАТЬ | СтруктураПредприятия.Ссылка | ИЗ | Справочник.СтруктураПредприятия КАК СтруктураПредприятия | ГДЕ | СтруктураПредприятия.Ссылка В ИЕРАРХИИ (&Подразделение))))) КАК ВыручкаИСебестоимостьПродажОбороты | ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.КлючиАналитикиУчетаНоменклатуры КАК КлючиАналитикиУчетаНоменклатуры | ПО ВыручкаИСебестоимостьПродажОбороты.АналитикаУчетаНоменклатуры = КлючиАналитикиУчетаНоменклатуры.Ссылка | ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.КлючиАналитикиУчетаПоПартнерам КАК КлючиАналитикиУчетаПоПартнерам | ПО ВыручкаИСебестоимостьПродажОбороты.АналитикаУчетаПоПартнерам = КлючиАналитикиУчетаПоПартнерам.Ссылка | |СГРУППИРОВАТЬ ПО | ВыручкаИСебестоимостьПродажОбороты.Период, | КлючиАналитикиУчетаПоПартнерам.Партнер.ОсновнойМенеджер.Наименование, | КлючиАналитикиУчетаНоменклатуры.Номенклатура.Родитель, | КлючиАналитикиУчетаПоПартнерам.Партнер.ОсновнойМенеджер.ТекущееПодразделение.Наименование + "" ("" + КлючиАналитикиУчетаПоПартнерам.Партнер.ОсновнойМенеджер.ТекущееПодразделение.Код + "")"", | КлючиАналитикиУчетаПоПартнерам.Партнер.Наименование + "" ("" + КлючиАналитикиУчетаПоПартнерам.Партнер.Код + "")"" | |УПОРЯДОЧИТЬ ПО | Ссылка, | Подразделение, | Менеджер, | Партнер |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | Партнеры.Наименование + "" ("" + Партнеры.Код + "")"" КАК Партнер, | Партнеры.ОсновнойМенеджер.Наименование КАК Менеджер, | Партнеры.ОсновнойМенеджер.ТекущееПодразделение.Наименование + "" ("" + Партнеры.ОсновнойМенеджер.ТекущееПодразделение.Код + "")"" КАК Подразделение, | 0 КАК Количество, | 0 КАК Выручка, | 0 КАК Себестоимость, | 0 КАК ДопРасходы |ИЗ | Справочник.Партнеры КАК Партнеры | ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Пользователи КАК Пользователи | ПО Партнеры.ОсновнойМенеджер = Пользователи.Ссылка |ГДЕ | Партнеры.Ссылка В | (ВЫБРАТЬ | ПартнерыСегмента.Партнер | ИЗ | РегистрСведений.ПартнерыСегмента КАК ПартнерыСегмента | ГДЕ | ПартнерыСегмента.Сегмент = &Сегмент) | И НЕ Партнеры.ОсновнойМенеджер = ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка) | И Пользователи.ТекущееПодразделение В | (ВЫБРАТЬ | СтруктураПредприятия.Ссылка | ИЗ | Справочник.СтруктураПредприятия КАК СтруктураПредприятия | ГДЕ | СтруктураПредприятия.Ссылка В ИЕРАРХИИ (&Подразделение))"; КонецФункции &НаСервереБезКонтекста Функция Transliterate(srtRusWord) Экспорт strRUS = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"; strENG = "A///B///V///G///D///E///YO//ZH//Z///I///Y///K///L///M///N///O///P///R///S///T///U///F///KH//TS//CH//SH//SHCH'///Y///////E///YU//JA//"; strResult = ""; Для i = 1 по СтрДлина(srtRusWord) Цикл s = Сред(srtRusWord, i,1); s=ВРег(s); k = Найти(strRUS, s); Если k = 0 тогда strResult = strResult + s; Иначе strResult = strResult + СтрЗаменить(Сред(strENG, (k - 1) * 4 + 1, 4), "/", ""); КонецЕсли КонецЦикла ; Возврат СокрЛП(strResult); КонецФункции &НаСервереБезКонтекста Функция ПолучитьНазваниеДляВыгрузки(НРодитель) //Родитель = Справочники.Номенклатура.СоздатьГруппу(); Если НРодитель=null or НРодитель.Пустая() тогда Возврат ""; КонецЕсли; СтрокаВозврата = ""; Если Не НРодитель.КодСортировки=0 тогда СтрокаВозврата = СтрокаВозврата + Формат(НРодитель.КодСортировки,"ЧЦ=3; ЧДЦ=0; ЧН=0; ЧВН=; ЧГ=0")+". "; КонецЕсли; СтрокаВозврата = СтрокаВозврата + НРодитель.Наименование + " (" + НРодитель.Код+")"; return СтрокаВозврата; КонецФункции &НаСервере Функция ВыгрузитьФайлик(СтруктФункц) Экспорт ВремяНачала = ТекущаяДата(); //ИмяФайлаЭксель = "C:\1\"+Transliterate(Подр.Наименование)+".xlsx"; // Имя создаваемого файла ИмяФайлаЭксель1 = КаталогВременныхФайлов()+Transliterate(СтруктФункц.Подр.Наименование)+".xlsx"; // Имя создаваемого файла ИмяФайлаЭксель = КаталогВременныхФайлов()+Transliterate(СтруктФункц.Подр.Наименование)+"(1).xlsx"; // Имя создаваемого файла ИмяФайлаZIP = КаталогВременныхФайлов()+Transliterate(СтруктФункц.Подр.Наименование)+".zip"; // Имя создаваемого файла УдалитьФайлы(ИмяФайлаЭксель); // Собираем строку подключения Command = Неопределено; //Connection.Close(); Connection = Неопределено; Table = Неопределено; Catalog = Неопределено; СтрокаПодключения = " |Provider=Microsoft.ACE.OLEDB.12.0; |Data Source="+ИмяФайлаЭксель+"; |Extended Properties=""Excel 12.0 Xml;HDR=YES;"";"; // Создаем соединение Connection = Новый COMОбъект("ADODB.Connection"); Connection.Open(СтрокаПодключения); Command = Новый COMОбъект("ADODB.Command"); Command.ActiveConnection = Connection; Command.CommandType = 1; Command.CommandText = "CREATE TABLE [Table] |( |Родитель1 char(120) WITH Compression |,Родитель2 char(120) WITH Compression |,НаправленияДеятельности char(50) WITH Compression |,Период date |,ПериодМесяц char(7) |,ПериодГод int |,Подразделение char(50) WITH Compression |,Менеджер char(50) WITH Compression |,Партнер char(50) WITH Compression |,Количество float |,Отгрузка currency |,Себестоимость currency |,ДопРасходы currency);"; Command.Execute(); // Получаем номенклатуру для выгрузки Запрос = Новый Запрос(ВернутьТекстЗапроса()); ПериодНачала = НачалоДня(СтруктФункц.ДатаНачала); ПериодОкончания = КонецДня(СтруктФункц.ДатаОкончания); Запрос.УстановитьПараметр("ПериодНачала",ПериодНачала);//НачалоМесяца(ТекущаяДата())); Запрос.УстановитьПараметр("ПериодОкончания",ПериодОкончания); Запрос.УстановитьПараметр("Организация",Справочники.Организации.НайтиПоНаименованию("Опт")); Запрос.УстановитьПараметр("Подразделение",СтруктФункц.Подр); Запрос.УстановитьПараметр("ПоказыватьСебестоимость",СтруктФункц.ПоказыватьСебестоимость); Запрос.УстановитьПараметр("Сегмент",Справочники.СегментыПартнеров.НайтиПоНаименованию("Рабочие")); Результат = Запрос.ВыполнитьПакет(); Выборка1 = Результат[0].Выбрать(); //Номенклатура Выборка2 = Результат[1].Выбрать(ОбходРезультатазапроса.ПоГруппировкам); // ВыручкаИСебестоимостьПродаж ВыборкаОбщий = Результат[2].Выбрать(); // Полный ТаблНоменклатура = Результат[0].Выгрузить(); ТаблНоменклатура.Колонки.Добавить("Родитель1",Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(120))); ТаблНоменклатура.Колонки.Добавить("Родитель2",Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(120))); ТаблНоменклатура.Колонки.Добавить("Группа1",Новый ОписаниеТипов("СправочникСсылка.Номенклатура")); ТаблНоменклатура.Колонки.Добавить("Группа2",Новый ОписаниеТипов("СправочникСсылка.Номенклатура")); ТаблНоменклатура.Колонки.Добавить("Количество",Новый ОписаниеТипов("Число",, Новый КвалификаторыЧисла(12,2))); ТаблНоменклатура.Колонки.Добавить("Отгрузка",Новый ОписаниеТипов("Число",, Новый КвалификаторыЧисла(12,2))); ТаблНоменклатура.Колонки.Добавить("Себестоимость",Новый ОписаниеТипов("Число",, Новый КвалификаторыЧисла(12,2))); ТаблНоменклатура.Колонки.Добавить("ДопРасходы",Новый ОписаниеТипов("Число",, Новый КвалификаторыЧисла(12,2))); Для Каждого СтрокаНом Из ТаблНоменклатура Цикл СтруктураГрупп = ВернутьГруппы(СтрокаНом.Ссылка); СтрокаНом.Родитель1 = СтруктураГрупп.Группа1С; СтрокаНом.Родитель2 = СтруктураГрупп.Группа2С; СтрокаНом.Группа1 = СтруктураГрупп.Группа1О; СтрокаНом.Группа2 = СтруктураГрупп.Группа2О; КонецЦикла; ТаблНоменклатура.Свернуть("Родитель1,Группа1,Родитель2,Группа2","Количество,Отгрузка,Себестоимость,ДопРасходы"); ТаблПродажи = Результат[1].Выгрузить(); ТаблПродажи.Колонки.Добавить("Родитель1",Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(120))); ТаблПродажи.Колонки.Добавить("Родитель2",Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(120))); ТаблПродажи.Колонки.Добавить("Группа1",Новый ОписаниеТипов("СправочникСсылка.Номенклатура")); ТаблПродажи.Колонки.Добавить("Группа2",Новый ОписаниеТипов("СправочникСсылка.Номенклатура")); Для Каждого СтрокаПродаж Из ТаблПродажи Цикл СтруктураГрупп = ВернутьГруппы(СтрокаПродаж.Ссылка); СтрокаПродаж.Родитель1 = СтруктураГрупп.Группа1С; СтрокаПродаж.Родитель2 = СтруктураГрупп.Группа2С; СтрокаПродаж.Группа1 = СтруктураГрупп.Группа1О; СтрокаПродаж.Группа2 = СтруктураГрупп.Группа2О; КонецЦикла; ТаблПродажи.Свернуть("Период,Менеджер,Подразделение,Партнер,Родитель1,Группа1,Родитель2,Группа2","Количество,Выручка,Себестоимость,ДопРасходы"); ПериодОкончанияНД = НачалоМесяца(ПериодОкончания); // Заполняем таблицу данными выборки Для Каждого СтрокаНом Из ТаблНоменклатура Цикл ВыборкаОбщий.Сбросить(); Пока ВыборкаОбщий.Следующий() Цикл Выборка= СоздатьСтруктуру(); ЗаполнитьЗначенияСвойств(Выборка,СтрокаНом); ЗаполнитьЗначенияСвойств(Выборка,ВыборкаОбщий); Выборка.Период = ПериодОкончанияНД;//ПериодНачала; Command.CommandText = СформироватьСтрокуЗапроса(Выборка); Command.Execute(); КонецЦикла; Для каждого НайденаяСтрока из ТаблПродажи.НайтиСтроки(Новый Структура("Группа1,Группа2",СтрокаНом.Группа1,СтрокаНом.Группа2)) Цикл Выборка= СоздатьСтруктуру(); ЗаполнитьЗначенияСвойств(Выборка,СтрокаНом); ЗаполнитьЗначенияСвойств(Выборка,НайденаяСтрока); Command.CommandText = СформироватьСтрокуЗапроса(Выборка); Command.Execute(); КонецЦикла; КонецЦикла; ВремяОкончания = ТекущаяДата(); Сообщить("Время начала:"+ВремяНачала); Сообщить("Время окончания:"+ВремяОкончания); // Закрываем соединение Command = Неопределено; Connection.Close(); Connection = Неопределено; Excel = новый COMОбъект("Excel.Application"); Excel.DisplayAlerts=0; Excel.Visible = 0; Excel.ScreenUpdating = False; Excel.EnableEvents = False; Книга = Excel.Workbooks.Open(ИмяФайлаЭксель); ОформитьПлан(Excel, Книга); Книга.Save(); Excel.Workbooks.Close(); Excel.Quit(); Excel=Неопределено; // СписокРассылки = Новый СписокЗначений; // СписокРассылки.Добавить("dyachok.n"); // // ФайлZip = Новый ЗаписьZipФайла(ИмяФайлаZIP,, "Выгрузка отгрузок", МетодСжатияZIP.Сжатие, УровеньСжатияZIP.Максимальный); // ФайлZip.Добавить(ИмяФайлаЭксель,РежимСохраненияПутейZIP.НеСохранятьПути,РежимОбработкиПодкаталоговZIP.НеОбрабатывать); // ФайлZip.Записать(); // ФайлZip = Неопределено; // // Мас = Новый Массив; // //ИмяФайлаНью = КаталогВременныхФайлов()+ИмяФайлаЭксель; // // Мас.Добавить(ИмяФайлаZIP); // // // //ИмяФайла = КаталогВременныхФайлов()+"Price_"+Формат(ДатаФормированияПрайса,"ДФ=yyyy-MM-dd")+".xls"; // //Мас.Добавить(ИмяФайла); // //ВыгрузитьВXLS(ИмяФайла); // ДанныеПисьма = Новый Структура("Тема,Тело","Информация по отгрузке:"+Подр,"Данные выгружены за период с "+Формат(ДатаНачала,"ДФ=dd.MM.yyyy")+" по "+Формат(ДатаОкончания,"ДФ=dd.MM.yyyy")); // Отправить(ДанныеПисьма,Мас,СписокРассылки); // УдалитьТемпФайл(ИмяФайлаZIP); // УдалитьТемпФайл(ИмяФайлаЭксель); // УдалитьТемпФайл(ИмяФайлаЭксель1); Адрес = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ИмяФайлаЭксель),СтруктФункц.ФормаУИД); Возврат Адрес; КонецФункции &НаСервереБезКонтекста Функция rgb(r,g,b) Возврат r+g*256+b*65536; КонецФункции &НаСервереБезКонтекста Функция ФЕ(ЧислоЗнч) Возврат Формат(ЧислоЗнч,"ЧЦ=10; ЧДЦ=0; ЧГ=0"); КонецФункции //http://www.tayloredmktg.com/rgb/ - цвета &НаСервереБезКонтекста Процедура ОформитьПлан(Знач Excel, Знач Книга) Лист = Книга.WorkSheets("Table"); Лист.Select(); ВсегоКолонок = Лист.Cells(1,1).SpecialCells(11).Column; ВсегоСтрок = Лист.Cells(1,1).SpecialCells(11).Row; Лист.Activate(); дДиапазонДанных=Лист.UsedRange.Address; ДиапазонДанных=Лист.Name+"!"+Строка(дДиапазонДанных); xlDatabase = 1; SourceType = xlDatabase; SourceData = ДиапазонДанных; TableDestination=""; TableName="Plan"; ЛистА = Книга.Sheets.Add(,Excel.Sheets("Table")); Е = Excel.ActiveWorkbook.PivotCaches().Create(xlDatabase, ДиапазонДанных, 4); СВТ = Е.CreatePivotTable(ЛистА.Name+"!R3C1", TableName, 4); СВТ.SubtotalLocation(1); СВТ.RowAxisLayout(2); СВТ.TableStyle2 = "PivotStyleMedium2"; СВТПодразделение = СВТ.PivotFields("Подразделение"); СВТПодразделение.Orientation = 1; СВТПодразделение.Position = 1; СВТМенеджер = СВТ.PivotFields("Менеджер"); СВТМенеджер.Orientation = 1; СВТМенеджер.Position = 2; СВТПартнер = СВТ.PivotFields("Партнер"); СВТПартнер.Orientation = 1; СВТПартнер.Position = 3; СВТРодитель1 = СВТ.PivotFields("Родитель1"); СВТРодитель1.Orientation = 1; СВТРодитель1.Position = 4; СВТРодитель2 = СВТ.PivotFields("Родитель2"); СВТРодитель2.Orientation = 1; СВТРодитель2.Position = 5; СВТПериодМесяц = СВТ.PivotFields("ПериодМесяц"); СВТПериодМесяц.Orientation = 2; СВТПериодМесяц.Position = 1; СВТ.AddDataField(СВТ.PivotFields("Количество"),"(Кол-во)",-4157); СВТ.AddDataField(СВТ.PivotFields("Отгрузка"),"(Отгрузка)",-4157); ВсегоКолонок1 = ЛистА.Cells(1,1).SpecialCells(11).Column; ВсегоСтрок1 = ЛистА.Cells(1,1).SpecialCells(11).Row; ЛистА.Activate(); Книга.ActiveSheet.Name = "План1"; дДиапазонДанных=ЛистА.UsedRange.Address; ДиапазонДанных=ЛистА.Name+"!"+Строка(дДиапазонДанных); Excel.Range(ДиапазонДанных).copy(); ЛистИ = Книга.Sheets.Add(,Excel.Sheets("План1")); ЛистИ.Name = "План"; ЛистИ.Select(); ЛистИ.Range("A1").Select(); Excel.Range("План!A1").PasteSpecial(-4163,-4142,false,false); Excel.Sheets("План1"). delete(); Excel.Sheets("Table").delete(); ЛистИ.Outline.SummaryRow = 0; // группировка сверху ВсегоКолонок = ЛистИ.Cells(1,1).SpecialCells(11).Column; ВсегоСтрок = ЛистИ.Cells(1,1).SpecialCells(11).Row; //Дальше формируем группировку ОбщСтр = Новый Структура; Для х=1 по 4 Цикл ОбщСтр.Вставить("Гр"+ФЕ(х),Новый Структура("ТекЗнач,НачЗнач,НачСтрока")); КонецЦикла; RangeCopy = ЛистИ.Range("$"+КЕ(6)+"$"+ФЕ(1)+":$"+КЕ(6+1)+"$"+ФЕ(ВсегоСтрок)); RangeCopy.Insert(-4161,0); Range = ЛистИ.Range("$"+КЕ(6)+"$"+ФЕ(1)+":$"+КЕ(6+1)+"$"+ФЕ(ВсегоСтрок)); Range.Interior.Color = rgb(135,206,250); Range.Borders(1).Weight = 2; Range.Borders(2).Weight = 2; Range.Borders(3).Weight = 2; Range.Borders(4).Weight = 2; RangePlan = ЛистИ.Range("$"+КЕ(6)+"$"+ФЕ(1)+":$"+КЕ(6+1)+"$"+ФЕ(1)); RangePlan.Merge(); RangePlan.Value="План"; Range = ЛистИ.Range("$"+КЕ(6)+"$"+ФЕ(2)+":$"+КЕ(6+1)+"$"+ФЕ(2)); Range.Merge(); ЛистИ.Cells(3, 6).Value = "(Кол-во)"; ЛистИ.Cells(3, 7).Value ="(Отгрузка)"; Range = ЛистИ.Range("$A$1:$"+КЕ(ВсегоКолонок+2)+"$3"); Range.Font.Name = "Arial Narrow"; Range.Font.Size = 12; Range.HorizontalAlignment =3; Range.VerticalAlignment =2; Range.Borders(1).Weight = 2; Range.Borders(2).Weight = 2; Range.Borders(3).Weight = 2; Range.Borders(4).Weight = 2; Range.Interior.Color = rgb(54,96,146); Range.Font.Color = rgb(255,255,255); Для СуммКол = 6 по ВсегоКолонок Цикл Если СуммКол%2 тогда ЛистИ.Columns(СуммКол).NumberFormat ="# ##0,00"; Иначе ЛистИ.Columns(СуммКол).NumberFormat ="# ##0"; Если НЕ СуммКол+2>ВсегоКолонок тогда Range = ЛистИ.Range("$"+КЕ(СуммКол)+"$"+ФЕ(2)+":$"+КЕ(СуммКол+1)+"$"+ФЕ(2)); Range.Merge(); КонецЕсли; КонецЕсли; КонецЦикла; Для СуммКол = ВсегоКолонок по ВсегоКолонок+2 Цикл // Для итогов не объединяем. Если СуммКол%2 тогда ЛистИ.Columns(СуммКол).NumberFormat ="# ##0,00"; Иначе ЛистИ.Columns(СуммКол).NumberFormat ="# ##0"; КонецЕсли; КонецЦикла; ВсегоКолонок = ВсегоКолонок+2; Для СтрокаЕ=4 по ВсегоСтрок Цикл Для х=1 по 4 Цикл ОбщСтр["Гр"+х].ТекЗнач = ЛистИ.Cells(СтрокаЕ, х).Value; Если (Не ПустаяСтрока(ОбщСтр["Гр"+х].ТекЗнач) И ОбщСтр["Гр"+х].ТекЗнач<>ОбщСтр["Гр"+х].НачЗнач) тогда Если НЕ ОбщСтр["Гр"+х].НачЗнач=НЕопределено тогда ЛистИ.Range("A"+ФЕ(ОбщСтр["Гр"+х].НачСтрока+1)+":"+КЕ(х)+ФЕ(СтрокаЕ-1)).Rows.Group(); Для у=х+1 по 4 Цикл ЛистИ.Range("A"+ФЕ(ОбщСтр["Гр"+у].НачСтрока+1)+":"+КЕ(у)+ФЕ(СтрокаЕ-1)).Rows.Group(); Для СуммКол = 6 по 8 Цикл ЛистИ.Cells(ОбщСтр["Гр"+у].НачСтрока, СуммКол).FormulaR1C1 = "=SUMIF(R[1]C["+ФЕ(5-СуммКол)+"]:R["+ФЕ(СтрокаЕ-ОбщСтр["Гр"+у].НачСтрока-1)+"]C["+ФЕ(5-СуммКол)+"],""*"",R[1]C:R["+ФЕ(СтрокаЕ-ОбщСтр["Гр"+у].НачСтрока-1)+"]C)"; КонецЦикла; ОбщСтр["Гр"+у].НачЗнач = Неопределено; ОбщСтр["Гр"+у].НачСтрока = СтрокаЕ-1; КонецЦикла; Для СуммКол = 6 по 8 Цикл ЛистИ.Cells(ОбщСтр["Гр"+х].НачСтрока, СуммКол).FormulaR1C1 = "=SUMIF(R[1]C["+ФЕ(5-СуммКол)+"]:R["+ФЕ(СтрокаЕ-ОбщСтр["Гр"+х].НачСтрока-1)+"]C["+ФЕ(5-СуммКол)+"],""*"",R[1]C:R["+ФЕ(СтрокаЕ-ОбщСтр["Гр"+х].НачСтрока-1)+"]C)"; КонецЦикла; КонецЕсли; ОбщСтр["Гр"+х].НачСтрока = СтрокаЕ; ОбщСтр["Гр"+х].НачЗнач = ОбщСтр["Гр"+х].ТекЗнач; Range = ЛистИ.Range("$"+КЕ(х)+"$"+ФЕ(СтрокаЕ)+":$"+КЕ(ВсегоКолонок)+"$"+ФЕ(СтрокаЕ)); Range.Font.Size = 16-х; Range.Interior.Color = rgb(255,255,255-(х*10)); ИначеЕсли НЕ ПустаяСтрока(ОбщСтр["Гр"+х].НачЗнач) тогда //ЛистИ.Cells(СтрокаЕ, х).Value = ОбщСтр["Гр"+х].НачЗнач; //ЛистИ.Cells(СтрокаЕ, х).Font.Color= rgb(255,255,255); КонецЕсли; КонецЦикла; КонецЦикла; ЛистИ.Cells.EntireColumn.AutoFit(); КонецПроцедуры &НаСервереБезКонтекста Функция КЕ(Номерколонки) // преобразуем число в колонку excel Дивиденд = Номерколонки; Модуль=0; СтрВозврата=""; Пока Дивиденд > 0 Цикл Модуль = (Дивиденд-1) % 26; Симв = Символ(65+Модуль); СтрВозврата = Симв+СтрВозврата; Дивиденд = Окр((Дивиденд - Модуль) / 26); КонецЦикла; Возврат СтрВозврата; КонецФункции &НаСервереБезКонтекста Функция СоздатьСтруктуру() Возврат Новый Структура("Код |,Наименование |,Родитель1 |,Родитель2 |,Родитель3 |,Родитель4 |,НаправленияДеятельности |,Период |,Подразделение |,Менеджер |,Партнер |,Количество |,Выручка |,Себестоимость |,ДопРасходы"); КонецФункции &НаСервереБезКонтекста Функция СформироватьСтрокуЗапроса(СтруктураВыборки) Возврат "INSERT INTO [Table] VALUES (" +"'"+СтрЗаменить(СтруктураВыборки.Родитель1,"'","''")+"'" +",'"+СтрЗаменить(СтруктураВыборки.Родитель2,"'","''")+"'" +",'"+СтрЗаменить(СтруктураВыборки.НаправленияДеятельности,"'","''")+"'" +",'"+СтрЗаменить(Формат(СтруктураВыборки.Период,"ДФ=MM/dd/yyyy"),"'","''")+"'" +",'"+СтрЗаменить(Формат(СтруктураВыборки.Период,"ДФ=MM.yyyy"),"'","''")+"'" +","+Формат(СтруктураВыборки.Период,"ДФ=yyyy")+"" +",'"+СтрЗаменить(СтруктураВыборки.Подразделение,"'","''")+"'" +",'"+СтрЗаменить(СтруктураВыборки.Менеджер,"'","''")+"'" +",'"+СтрЗаменить(СтруктураВыборки.Партнер,"'","''")+"'" +","+Формат(СтруктураВыборки.Количество,"ЧЦ=12; ЧДЦ=0; ЧРД=.; ЧН=0; ЧГ=0")+"" +","+Формат(СтруктураВыборки.Выручка,"ЧЦ=12; ЧДЦ=2; ЧРД=.; ЧН=0; ЧГ=0")+"" +","+Формат(СтруктураВыборки.Себестоимость,"ЧЦ=12; ЧДЦ=2; ЧРД=.; ЧН=0; ЧГ=0")+"" +","+Формат(СтруктураВыборки.ДопРасходы,"ЧЦ=12; ЧДЦ=2; ЧРД=.; ЧН=0; ЧГ=0")+"" +");"; КонецФункции &НаКлиенте Процедура ПриОткрытии(Отказ) КонецПроцедуры &НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) ЭтаФорма.Подразделение = Справочники.СтруктураПредприятия.НайтиПоНаименованию("Опт"); ЭтаФорма.ПериодОтчета.Вариант=ВариантСтандартногоПериода.ПрошлыйКвартал; КонецПроцедуры Процедура Отправить(ДанныеПисьма,Вложения,Знач Кому) экспорт //для получения доступа к набору свойств для соединения с сервером //создадим новый объект Профиль = Новый ИнтернетПочтовыйПрофиль; //Пропишем параметры соединения //ip адрес или имя SMTP сервера Профиль.АдресСервераSMTP = "*********"; //Порт SMTP сервера Профиль.ПортSMTP = "25"; //Имя пользователя почтового ящика Профиль.Пользователь = "user********"; //Пароль доступа к почтовому ящику Профиль.Пароль = "*****************"; //При необходимости добавляем аутентификацию Профиль.АутентификацияSMTP = СпособSMTPАутентификации.Login; Профиль.ПарольSMTP = Профиль.Пароль; Профиль.ПользовательSMTP = Профиль.Пользователь; // Создаем объект для работы с почтой Почта = Новый ИнтернетПочта; //Выполняем подключение, согласно указанный параметров Попытка Почта.Подключиться(Профиль); Исключение //При подключении возникла ошибка, сообщим Сообщить("Ошибка при подключении к серверу" + ОписаниеОшибки()); Возврат; КонецПопытки; //Создаем новое письмо (сообщение) Сообщение = Новый ИнтернетПочтовоеСообщение; //Указываем отправителя Сообщение.Отправитель = "user********"; Для Каждого ЗначКому из Кому Цикл Сообщение.Получатели.Добавить(ЗначКому); КонецЦикла; //Заполняем получателя //Сообщение.Получатели.Добавить("dyachok.n@"); //Пишем тему письма Сообщение.Тема = ДанныеПисьма.Тема; //Формируем текст письма,указываем тип письма Сообщение.Тексты.Добавить(ДанныеПисьма.Тело,ТипТекстаПочтовогоСообщения.HTML); //При необходимости делаем вложение с файлом Если ТипЗнч(Вложения)= Тип("Строка") тогда Сообщение.Вложения.Добавить(Вложения); ИначеЕсли ТипЗнч(Вложения) = Тип("Массив") тогда Для Каждого Файл из Вложения Цикл Сообщение.Вложения.Добавить(Файл); КонецЦикла; КонецЕсли; //Непосредственно отправка сообщения Почта.Послать(Сообщение); //После отправки закрываем соединение Почта.Отключиться(); Сообщение = Неопределено; Почта = Неопределено; КонецПроцедуры Процедура УдалитьТемпФайл(ИмяФайла) ФайлНаДиске = Новый Файл(ИмяФайла); Если ФайлНаДиске.Существует() тогда УдалитьФайлы(ИмяФайла); КонецЕсли; КонецПроцедуры &НаСервереБезКонтекста Функция ВернутьГруппы(Знач Ном) //Ном = Справочники.Номенклатура.СоздатьЭлемент(); СтруктураГрупп = Новый Структура("Группа1О,Группа2О,Группа3О,Группа1С,Группа2С,Группа3С"); Поиск = Ном; ТекУровень = Поиск.Уровень(); Пока Истина Цикл Если Поиск.Пустая() тогда прервать; КонецЕсли; Если НЕ Поиск.ЭтоГруппа тогда Поиск = Поиск.Родитель; продолжить; КонецЕсли; ТекУровень = Поиск.Уровень()+1; Если ТекУровень = 1 тогда СтруктураГрупп.Группа1О = Поиск; СтрокаВозврата = ""; Если НЕ Поиск.КодСортировки=0 тогда СтрокаВозврата=СтрокаВозврата+Формат(Поиск.КодСортировки,"ЧЦ=3; ЧДЦ=0; ЧН=0; ЧВН=; ЧГ=0")+". "; КонецЕсли; СтруктураГрупп.Группа1С=СтрокаВозврата+Поиск.Наименование + " ("+Поиск.Код +")"; ИначеЕсли ТекУровень = 2 тогда СтруктураГрупп.Группа2О = Поиск; СтрокаВозврата = ""; Если НЕ Поиск.КодСортировки=0 тогда СтрокаВозврата=СтрокаВозврата+Формат(Поиск.КодСортировки,"ЧЦ=3; ЧДЦ=0; ЧН=0; ЧВН=; ЧГ=0")+". "; КонецЕсли; СтруктураГрупп.Группа2С=СтрокаВозврата+Поиск.Наименование + " ("+Поиск.Код +")"; ИначеЕсли ТекУровень = 3 тогда СтруктураГрупп.Группа3О = Поиск; СтрокаВозврата = ""; Если НЕ Поиск.КодСортировки=0 тогда СтрокаВозврата=СтрокаВозврата+Формат(Поиск.КодСортировки,"ЧЦ=3; ЧДЦ=0; ЧН=0; ЧВН=; ЧГ=0")+". "; КонецЕсли; СтруктураГрупп.Группа3С=СтрокаВозврата+Поиск.Наименование + " ("+Поиск.Код +")"; КонецЕсли; Поиск = Поиск.Родитель; КонецЦикла; Возврат СтруктураГрупп; КонецФункции