Попала в руки одна демка системы по работе с прайсами, решил попробовать интегрировать ее в Альфа-Авто чтобы протестировать и посмотреть ее возможности. Объединил, но видимых изменений не произошло, модули добавились, а в интерфейсе ничего не поменялось. Посмотрел описание, а эта система только под УправлениеТорговли заточена. Решил, что тогда хоть попробую понять по каким алгоритмам оно работает. Нашел один закрытый модуль, декомпилировал его и тут меня чуть не хватил удар от увиденного каламбура.
То что человеческое форматирование и правила хорошего тона при написания кода отсутствует напрочь, но то как перемешаны процедуры и функции вообще вводит в ступор и вызывает вывих мозга. Также бессмысленное объявление переменных с непонятными именами и присвоениями, непонятные циклы и множественные переходы к меткам, которые или вызывают зацикливание функции/процедуры или до этого перехода выполнение никогда не доберется по причине расположенного перед ним другого перехода или оператора Возврат. Или непонятный код, который расположен в межпроцедурном или в межфункциональном пространстве - как такое может вообще работать и как на это не ругается интерпретатор.
Складывается, что этот модуль был обработан каким-то алгоритмом для запутывания кода .
logist @ Сегодня, 0:51
, На протяжение двух лет я находил несколько серьезных косяков в работе Альфы, о чем сообщал в поддержку 1С-Рарус Украина, которые пытались воссоздать "глюки" у себя и когда они подтверждали, то передавали на исправление разработчикам. Мне отвечали, что исправления будут в следующих релизах. Вот и хочу, чтобы эти исправления были и у меня.
Но самое главное, хочу освоить этот процесс для собственного развития.
Все получилось как и хотел. Добавил следующий код в форму списка документа РеализацияТоваров
Перем СкладКод, ЦветСтрок; ... Процедура СписокПриПолученииДанных(Элемент, ОформленияСтрок) Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл ... Попытка Если ОформлениеСтроки.ДанныеСтроки.Ссылка.СкладКомпании.Код = СкладКод Тогда ОформлениеСтроки.ЦветФона = ЦветСтрок; КонецЕсли; Исключение КонецПопытки; КонецЦикла; КонецПроцедуры //СписокПриПолученииДанных()
... Процедура ПриОткрытии() ... ТекПользователь = ПользователиИнформационнойБазы.ТекущийПользователь(); СпрТекПольз = Справочники.Пользователи.НайтиПоКоду(ТекПользователь.Имя); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | НастройкиПользователей.Пользователь, | НастройкиПользователей.Назначение, | НастройкиПользователей.Склад, | НастройкиПользователей.Цвет, | НастройкиПользователей.Склад.Код КАК КодСклада |ИЗ | Справочник.НастройкиПользователей КАК НастройкиПользователей |ГДЕ | НастройкиПользователей.Пользователь = &Пользователь"; Запрос.УстановитьПараметр("Пользователь", СпрТекПольз); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() Цикл СкладКод = Выборка.КодСклада; ЦветСтрок = Выборка.Цвет.Получить(); КонецЦикла; КонецПроцедуры // ПриОткрытии()
В справочнике настроек форма элемента так
Процедура кнВыбратьЦветНажатие(Элемент) Диалог = Новый ДиалогВыбораЦвета; Если Диалог.Выбрать() Тогда ВыбранныйЦвет = Диалог.Цвет; Цвет = Новый ХранилищеЗначения(ВыбранныйЦвет); ЭлементыФормы.ПримерЦвета.ЦветФонаПоля = ВыбранныйЦвет; //подсвечиваем чтобы пользователь мог видеть как выглядит КонецЕсли; КонецПроцедуры
Процедура ПриОткрытии() ЭлементыФормы.ПримерЦвета.Значение = "Это пример отображения"; Попытка ЭлементыФормы.ПримерЦвета.ЦветФонаПоля = Цвет.Получить(); // чтобы было видно какой цвет установлен Исключение КонецПопытки; КонецПроцедуры
Курс "Практическое применение системы компоновки данных". Авторы: к сожалению неизвестно, но использовались материалы из книги Е.Ю. Хрусталевой "Разработка сложных отчетов в 1С:Предприятии 8. Система компоновки данных".
Вот содержание 1. Шаг первый. Простой отчет без кодирования. 2. Немного теории. Устройство системы компоновки данных 3. Шаг второй. Работа с параметрами и отборами 4. Шаг третий. Работа с различными наборами данных. Внешние наборы данных 5. Шаг четвертый. Макеты компоновки данных. Создание собственных макетов 6. Шаг пятый. Использование характеристик. Условное оформление. Вычисляемые поля. 7. Шаг шестой. Расшифровка.
Закончил данную обработку. Вот ключевые участки кода:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Процедура ПереносОстатков() СпрСклады = Справочники.СкладыКомпании.Выбрать(); Пока СпрСклады.Следующий() Цикл ВводОстатков = Документы.ВводОстатковТоваров.СоздатьДокумент(); ВводОстатков.Комментарий = "Перенос остатков при свертке ИБ"; ВводОстатков.СкладКомпании = СпрСклады.Ссылка; ВводОстатков.Автор = Справочники.Пользователи.НайтиПоНаименованию(ПользователиИнформационнойБазы.ТекущийПользователь().Имя); ВводОстатков.Организация = Справочники.Организации.НайтиПоНаименованию("ГРАНД-АВТО"); ВводОстатков.ПодразделениеКомпании = Справочники.ПодразделенияКомпании.НайтиПоНаименованию("ГРАНД-АВТО"); ВводОстатков.Контрагент = Справочники.Контрагенты.НайтиПоНаименованию("АВТОСКЛАД"); ВводОстатков.ДоговорВзаиморасчетов = Справочники.ДоговорыВзаиморасчетов.НайтиПоКоду("ЦБ000001"); ВалютаДок = Справочники.Валюты.НайтиПоКоду("840"); КурсДок = РегистрыСведений.КурсыВалют.ПолучитьПоследнее(пвДатаСвертки, Новый Структура("Валюта", ВалютаДок)); ВводОстатков.ВалютаДокумента = ВалютаДок; ВводОстатков.КурсДокумента = КурсДок.Курс; ВводОстатков.ХозОперация = Справочники.ХозОперации.ВводОстатковТоваров; ВводОстатков.Дата = КонецДня(пвДатаСвертки)+1; // Дата документа с начала дня следующего числа ВводОстатков.СтатьяОприходованияТМЦ = Справочники.СтатьиДоходовИРасходов.НайтиПоКоду("30003"); ТЧ = ВводОстатков.Товары; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ОстаткиТоваровКомпанииОстатки.Номенклатура, | ОстаткиТоваровКомпанииОстатки.КоличествоОстаток, | ОстаткиТоваровКомпанииОстатки.СкладКомпании |ИЗ | РегистрНакопления.ОстаткиТоваровКомпании.Остатки(&Дата, ) КАК ОстаткиТоваровКомпанииОстатки |ГДЕ | ОстаткиТоваровКомпанииОстатки.СкладКомпании = &СкладКомпании"; Запрос.УстановитьПараметр("СкладКомпании", СпрСклады.Ссылка); Запрос.УстановитьПараметр("Дата", пвДатаСвертки); Выборка = Запрос.Выполнить().Выбрать(); ЭлементыФормы.Индикатор.МинимальноеЗначение = 0; ЭлементыФормы.Индикатор.МаксимальноеЗначение = Выборка.Количество(); ЭлементыФормы.Индикатор.Значение = 0; Пока Выборка.Следующий() Цикл НоваяСтрокаТЧ = ТЧ.Добавить(); НоваяСтрокаТЧ.Номенклатура = Выборка.Номенклатура; ВводОстатков.ОбработкаРеквизита("Товары.Номенклатура",НоваяСтрокаТЧ,); НоваяСтрокаТЧ.Количество = Выборка.КоличествоОстаток; ВводОстатков.ОбработкаРеквизита("Товары.Количество",НоваяСтрокаТЧ,); Отбор = Новый Структура("ТипЦен, Номенклатура"); Отбор.ТипЦен = ВводОстатков.ДоговорВзаиморасчетов.ТипЦенПокупки; // Какой тип цены Отбор.Номенклатура = Выборка.Номенклатура; // Для какой номенклатуры Цена = РегистрыСведений.Цены.СрезПоследних( пвДатаСвертки, Отбор); Для каждого стр из Цена Цикл НоваяСтрокаТЧ.Цена = стр.Цена; ВводОстатков.ОбработкаРеквизита("Товары.Цена",НоваяСтрокаТЧ,); КонецЦикла; ЭлементыФормы.Индикатор.Значение = ЭлементыФормы.Индикатор.Значение+1; ОбработкаПрерыванияПользователя(); КонецЦикла; ВводОстатков.Записать(); ЭлементыФормы.Индикатор.Значение = 0; КонецЦикла; КонецПроцедуры ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Процедура ПереносЦен() Для каждого СтрЦена из тпНастройкаЦен Цикл ДокИзмЦен = Документы.ИзменениеЦен.СоздатьДокумент(); ДокИзмЦен.ОбработкаЗаполнения(Неопределено); ДокИзмЦен.Комментарий = "Перенос цен при свертке ИБ"; ДокИзмЦен.Дата = КонецДня(пвДатаСвертки)+1; // Дата документа с начала дня следующего числа пвДатаСвертки; ДокИзмЦен.ХозОперация = Справочники.ХозОперации.УстановкаЦенКомпании; //Док.УстановитьНовыйНомер(); ДокИзмЦен.ДатаНачалаДействия = пвДатаСвертки; ДокИзмЦен.Организация = Справочники.Организации.НайтиПоНаименованию("ГРАНД-АВТО"); ДокИзмЦен.ПодразделениеКомпании = Справочники.ПодразделенияКомпании.НайтиПоНаименованию("ГРАНД-АВТО");; ДокИзмЦен.ТипЦен = СтрЦена.ТипЦены; ВалютаДок = Справочники.Валюты.НайтиПоКоду("840"); КурсДок = РегистрыСведений.КурсыВалют.ПолучитьПоследнее(пвДатаСвертки, Новый Структура("Валюта", ВалютаДок)); ДокИзмЦен.ВалютаДокумента = ВалютаДок; ДокИзмЦен.КурсДокумента = КурсДок.Курс; ДокИзмЦен.РасчетЦенОт = 2; //Выставляем "От цен поставщика" //ДокИзмЦен.Поставщик = Справочники.Контрагенты.НайтиПоНаименованию("АВТОСКЛАД"); ТЧ = ДокИзмЦен.Товары; ОтборТипЦен = Новый Структура("ТипЦен", СтрЦена.ТипЦены); тзДанные = РегистрыСведений.Цены.СрезПоследних(пвДатаСвертки, ОтборТипЦен); ЭлементыФормы.Индикатор.МинимальноеЗначение = 0; ЭлементыФормы.Индикатор.МаксимальноеЗначение = тзДанные.Количество(); ЭлементыФормы.Индикатор.Значение = 0; Для Каждого Стр Из тзДанные Цикл НайденнаяСтрока = ТЧ.Найти(Стр.Номенклатура,"Номенклатура"); Если НайденнаяСтрока = Неопределено Тогда СтрокаТоваров= ТЧ.Добавить(); СтрокаТоваров.Номенклатура = Стр.Номенклатура; ДокИзмЦен.ОбработкаРеквизита("Товары.Номенклатура",СтрокаТоваров,); КонецЕсли; ЭлементыФормы.Индикатор.Значение = ЭлементыФормы.Индикатор.Значение+1; КонецЦикла; ДокИзмЦен.Записать(); ЭлементыФормы.Индикатор.Значение = 0; КонецЦикла; КонецПроцедуры ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Процедура ПереносВзаиморасчетов() СпрВалюты = Справочники.Валюты.Выбрать(); Пока СпрВалюты.Следующий() Цикл ДокВзаиморасч = Документы.ВводОстатковВзаиморасчетов.СоздатьДокумент(); ДокВзаиморасч.Комментарий = "Перенос цен при свертке ИБ"; ДокВзаиморасч.Организация = Справочники.Организации.НайтиПоНаименованию("ГРАНД-АВТО");; ДокВзаиморасч.ПодразделениеКомпании = Справочники.ПодразделенияКомпании.НайтиПоНаименованию("ГРАНД-АВТО");;; ДокВзаиморасч.ВалютаДокумента = СпрВалюты.Ссылка; ДокВзаиморасч.Дата = КонецДня(пвДатаСвертки)+1; // Дата документа с начала дня следующего числа пвДатаСвертки; ДокВзаиморасч.Автор = Справочники.Пользователи.НайтиПоНаименованию(ПользователиИнформационнойБазы.ТекущийПользователь().Имя); ДокВзаиморасч.РегламентированныйУчет = Истина; КурсДок = РегистрыСведений.КурсыВалют.ПолучитьПоследнее(пвДатаСвертки, Новый Структура("Валюта", СпрВалюты.Ссылка)); ДокВзаиморасч.КурсДокумента = КурсДок.Курс; ДокВзаиморасч.ХозОперация = Справочники.ХозОперации.ВводОстатковВзаиморасчетов; ТЧ = ДокВзаиморасч.Состав; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ВзаиморасчетыКомпанииОстаткиИОбороты.Контрагент КАК Контрагент, | ВзаиморасчетыКомпанииОстаткиИОбороты.ДоговорВзаиморасчетов КАК ДоговорВзаиморасчетов, | ВзаиморасчетыКомпанииОстаткиИОбороты.Сделка КАК Сделка, | ВзаиморасчетыКомпанииОстаткиИОбороты.СуммаКонечныйОстаток КАК Сумма, | ВзаиморасчетыКомпанииОстаткиИОбороты.СуммаУпрКонечныйОстаток КАК СуммаУпр, | ВзаиморасчетыКомпанииОстаткиИОбороты.СуммаБазКонечныйОстаток КАК СуммаБаз |ИЗ | РегистрНакопления.ВзаиморасчетыКомпании.ОстаткиИОбороты(, &Дата, , , ) КАК ВзаиморасчетыКомпанииОстаткиИОбороты |ГДЕ | ВзаиморасчетыКомпанииОстаткиИОбороты.ДоговорВзаиморасчетов.ВалютаВзаиморасчетов = &ВалютаВзаиморасчетов"; Запрос.УстановитьПараметр("Дата", пвДатаСвертки); Запрос.УстановитьПараметр("ВалютаВзаиморасчетов",СпрВалюты.Ссылка); Результат = Запрос.Выполнить(); ТЗ = Новый ТаблицаЗначений; ОписаниеКонтрагента = Новый ОписаниеТипов("СправочникСсылка.Контрагенты"); ОписаниеДоговорВзаиморасчетов = Новый ОписаниеТипов("СправочникСсылка.ДоговорыВзаиморасчетов"); ОписаниеСтроки = Новый ОписаниеТипов("Строка"); ОписаниеСуммы = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(12, 3)); ТЗ.Колонки.Добавить("Контрагент",ОписаниеКонтрагента); ТЗ.Колонки.Добавить("ДоговорВзаиморасчетов",ОписаниеДоговорВзаиморасчетов); ТЗ.Колонки.Добавить("Сделка",ОписаниеСтроки); ТЗ.Колонки.Добавить("Сумма",ОписаниеСуммы); ТЗ.Колонки.Добавить("СуммаУпр",ОписаниеСуммы); ТЗ.Колонки.Добавить("СуммаБаз",ОписаниеСуммы); ТЗ = Результат.Выгрузить(); ТЗ.Свернуть("Контрагент, ДоговорВзаиморасчетов" ,"Сумма, СуммаУпр, СуммаБаз"); ЭлементыФормы.Индикатор.МинимальноеЗначение = 0; ЭлементыФормы.Индикатор.МаксимальноеЗначение = ТЗ.Количество(); ЭлементыФормы.Индикатор.Значение = 0; Для каждого стр из ТЗ Цикл Сумма = ?(ПустаяСтрока(стр.Сумма), 0, стр.Сумма); Если Сумма > 0 Тогда СтрокаТоваров= ТЧ.Добавить(); СтрокаТоваров.Контрагент = Стр.Контрагент; ДокВзаиморасч.ОбработкаРеквизита("Состав.Контрагент",СтрокаТоваров,); СтрокаТоваров.ДоговорВзаиморасчетов = Стр.ДоговорВзаиморасчетов; ДокВзаиморасч.ОбработкаРеквизита("Состав.ДоговорВзаиморасчетов",СтрокаТоваров,); СтрокаТоваров.СуммаДебет = Сумма; ИначеЕсли Сумма < 0 Тогда СтрокаТоваров= ТЧ.Добавить(); СтрокаТоваров.Контрагент = Стр.Контрагент; ДокВзаиморасч.ОбработкаРеквизита("Состав.Контрагент",СтрокаТоваров,); СтрокаТоваров.ДоговорВзаиморасчетов = Стр.ДоговорВзаиморасчетов; ДокВзаиморасч.ОбработкаРеквизита("Состав.ДоговорВзаиморасчетов",СтрокаТоваров,); СтрокаТоваров.СуммаКредит = Макс(-Сумма, Сумма); КонецЕсли; ЭлементыФормы.Индикатор.Значение = ЭлементыФормы.Индикатор.Значение+1; КонецЦикла; ДокВзаиморасч.Записать(); ЭлементыФормы.Индикатор.Значение = 0; КонецЦикла; КонецПроцедуры ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Процедура УстановкаПометкиУдаления() Запрос = Новый Запрос; ФлагПервыйВход = Истина; Запрос.Текст = "ВЫБРАТЬ ВложенныйЗапрос.Ссылка ИЗ ("; Для каждого Док из Метаданные.Документы Цикл Если НЕ ФлагПервыйВход Тогда Запрос.Текст = Запрос.Текст + " ОБЪЕДИНИТЬ ВСЕ "; КонецЕСли; ФлагПервыйВход = Ложь; Запрос.Текст = Запрос.Текст + " ВЫБРАТЬ Ссылка ИЗ Документ." + Док.Имя + " ГДЕ Дата МЕЖДУ &НачДата и &КонДата "; КонецЦикла; Запрос.Текст = Запрос.Текст + ") КАК ВложенныйЗапрос УПОРЯДОЧИТЬ ПО ВложенныйЗапрос.Ссылка.Дата"; Запрос.УстановитьПараметр("НачДата", НачалоГода(пвДатаСвертки)); Запрос.УстановитьПараметр("КонДата", пвДатаСвертки); РезультатЗапроса = Запрос.Выполнить(); Выборка = РезультатЗапроса.Выбрать(); ЭлементыФормы.Индикатор.МинимальноеЗначение = 0; ЭлементыФормы.Индикатор.МаксимальноеЗначение = Выборка.Количество(); ЭлементыФормы.Индикатор.Значение = 0; Пока Выборка.Следующий() Цикл ЭлементыФормы.Индикатор.Значение = ЭлементыФормы.Индикатор.Значение+1; Попытка Объект = Выборка.Ссылка.ПолучитьОбъект(); Объект.УстановитьПометкуУдаления(Истина); Объект.Записать(); Исключение Сообщить("Ошибка установки пометки удаления: "+Выборка.Ссылка); КонецПопытки; ОбработкаПрерыванияПользователя(); КонецЦикла; ЭлементыФормы.Индикатор.Значение = 0; КонецПроцедуры
Насколько такой способ верный, т.к. первые тестирования показали, что вроде все работает и полученные в итоге цифры похожи на правду? Может быть стоит что-нибудь еще учесть?
Нашел способ как можно работать с перечислениями через СОМ
Ном = COM_ОбъектБД.Перечисления.ВидыТМЦ.Индекс(COM_ЭлементСправочника.Перечисление); Имя = COM_ОбъектБД.Метаданные().Перечисления.ВидПеречисления.EnumValues.Get(Ном).Name;
Получить значение перечисления
ИмяПеречисления = СсылкаНаПеречисление.Метаданные().Имя; КоличествоЗначенийПеречисления=Метаданные.Перечисления[ИмяПеречисления].ЗначенияПеречисления.Количество(); КолекцияЗначенийПеречисления = Метаданные.Перечисления[ИмяПеречисления].ЗначенияПеречисления; ИндексЗначенияПеречисления=Перечисления[ИмяПеречисления].Индекс(СсылкаНаПеречисление); ИмяЗначенияПеречисления = Метаданные.Перечисления[ИмяПеречисления].ЗначенияПеречисления[ИндексЗначенияПеречисления].Имя //Перебор коллекции значений перечисления Для каждого знач из КолекцияЗначенийПеречисления Цикл Сообщить(знач.Имя); КонецЦикла; ПредставлениеПеречисления=Строка(СсылкаНаПеречисление); //синоним
//полезной будет функция: Функция ПолучитьИмяЗначенияПеречисления(Ссылка) Экспорт
ИмяПеречисления = Ссылка.Метаданные().Имя; Индекс = Перечисления[ИмяПеречисления].Индекс(Ссылка);
// Альтернативный способ получения имени значения перечисления: ИмяЗначенияПеречисления = XMLстрока(СсылкаНаПеречисление);
// Полезный прием для работы с перечислениями при COM соединении с другой ИБ 8.0 (например при обмене данных): // надо передать ссылку на перечисление: // Здесь // V8 - COM объект "V8.Application" - ИБ внешнего соединения // СсылкаНаПеречислениеCOM - COM объект - ссылка на перечисление в ИБ внешнего соединения ИмяЗначенияПеречисленияCOM= V8.XMLString(СсылкаНаПеречислениеCOM); ПредставлениеПеречисленияCOM= V8.String(СсылкаНаПеречислениеCOM); //синоним ИмяПеречисленияCOM= СсылкаНаПеречислениеCOM.Метаданные().Имя; СсылкаНаПеречисление = XMLЗначение(Тип("ПеречислениеСсылка."+ИмяПеречисленияCOM), ИмяЗначенияПеречисленияCOM);
// разумеется имена перечислений в обоих базах должны быть идентичными.
// Пример получения значений перечисления запросом Запрос=новый запрос; запрос.Текст="ВЫБРАТЬ | ВидыОС.Ссылка, | ВидыОС.Порядок КАК Индекс |ИЗ | Перечисление.ВидыОС КАК ВидыОС"; Выборка=Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() цикл Сообщить(""+Выборка.ссылка+" : "+Выборка.индекс); конецЦикла;
// Пример для отбора на стороне COMсервера: Отбор = v8.Новый ("Структура"); МД=v8.XMLTypeOf(v8.Перечисления[ИмяПеречисления].ПустаяСсылка()); Отбор.Вставить("ВидДоговора", v8.XMLЗначение(v8.FromXMLType(МД),ИмяЗначенияПеречисления));
Получилось решить проблему привязок следующим образом: Элементы формы расположенные в верхней части формы переложил на панель, у которой убрал видимость закладок. Т.о. упростились привязки этих элементов и теперь элементы не сбиваются в кучу.
Теперь на форме вверху и в центре находятся панели, между которыми разделитель, а в нижней части табличное поле (между табличным полем и средней панелью разделителя нет).
1С Предприятие 8.3, 1С Предприятие 8.2, 1С Предприятие 8.1, 1С Предприятие 8.0, 1С Предприятие 7.7, Литература 1С, Общие вопросы по администрированию 1С, Методическая поддержка 1С - всё в одном месте: на Украинском 1С форуме!