17 окт. 2016 г.

История изменения объектов 1С

// Универсальная процедура, регистрирующая изменения реквизитов объекта (справочник, документ, план обмена, ПВХ)
// в журнале регистрации
//
Процедура РегистрацияИзмененийРеквизитовОбъекта(Объект) Экспорт
 Перем МетаданныеОбъекта;
 
 Если НЕ Объект.Ссылка.Пустая() Тогда
  
  МетаданныеОбъекта = Объект.Метаданные();
  
  СтрокаСобытие = "Данные.ИзменениеРеквизитов." + МетаданныеОбъекта.Имя;
  ПрежнийОбъект = Объект.Ссылка;
  РеквизитыПрежнегоОбъекта = ПолучитьРеквизитыОбъекта(ПрежнийОбъект);
  
  СтрокаСообщениеРеквизит = "Изменён реквизит ";
  СтрокаСообщениеТабЧасть = "Изменена таб.часть ";
  СтрокаСообщениеТабЧастьУдалено = "Удалено ";
  СтрокаСообщениеТабЧастьДобавлено = "Добавлено ";
  
  Для Каждого Элемент из РеквизитыПрежнегоОбъекта Цикл
   ПрежнийРеквизитЗначение = Элемент.Значение;
   НовыйРеквизитЗначение = Объект[Элемент.Ключ];
   Если ТипЗнч(НовыйРеквизитЗначение) = Тип("Строка") Тогда
    НовыйРеквизитЗначение = СокрЛП(НовыйРеквизитЗначение);
   КонецЕсли;
   Если ТипЗнч(ПрежнийРеквизитЗначение) = Тип("Строка") Тогда
    ПрежнийРеквизитЗначение = СокрЛП(ПрежнийРеквизитЗначение);
   КонецЕсли;
   Если ПрежнийРеквизитЗначение <> НовыйРеквизитЗначение Тогда
    ЗаписьЖурналаРегистрации(СтрокаСобытие, УровеньЖурналаРегистрации.Предупреждение, МетаданныеОбъекта, ПрежнийОбъект, СтрокаСообщениеРеквизит + Элемент.Ключ + Символы.ВК + "Прежний: " + Строка(ПрежнийРеквизитЗначение) + Символы.ВК + "Новый: " + Строка(НовыйРеквизитЗначение));
   КонецЕсли;
  КонецЦикла;
  
  Если МетаданныеОбъекта.ТабличныеЧасти.Количество() > 0 Тогда
   
   // Определяем список проверяемых реквизитов табличных частей,
   // чтобы не забивать журнал регистрации лишними записями.
   // Для каждой конфигурации определить свой список, либо удалить проверку
   // Здесь приведён пример для Управления Торговлей.
   ПроверяемыеРеквизитыТабЧасти = Новый Структура("Номенклатура, ЕдиницаИзмерения, Количество, Цена, Сумма, СтавкаНДС, СерияНоменклатуры, ХарактеристикаНоменклатуры, СерияНоменклатурыНовая, ХарактеристикаНоменклатурыНовая, СерияНоменклатурыСтарая, ХарактеристикаНоменклатурыСтарая, Проект, ЗаказПокупателя, Сделка, ДокументПартии, ДокументРасчетовСКонтрагентом, СуммаВзаиморасчетов, ДоговорКонтрагента, Контрагент, СтатьяДвиженияДенежныхСредств, ПроцентСкидкиНаценки, НаименованиеТовара, ЗаказПоставщику, ДокументПоступления, ДокументОснование, ИсходноеРазмещение, НовоеРазмещение, СуммаТовара, СуммаПлатежа, Размещение, УвеличениеДолгаКонтрагента, УменьшениеДолгаКонтрагента, КоличествоУчет, ДокументРезерва, ТипЦен, Валюта, Пользователь, ВидЗадолженности, ВидОперации");
   
   //This code is ported from http://www.kb.mista.ru/article.php?id=115
   Для Каждого МДТЧ ИЗ МетаданныеОбъекта.ТабличныеЧасти Цикл
    ИмяТЧ = МДТЧ.Имя;
    ТЧ1 = Объект[ИмяТЧ];
    ТЧ2 = ПрежнийОбъект[ИмяТЧ];
    ТЧ1Количество = ТЧ1.Количество();
    ТЧ2Количество = ТЧ2.Количество();
    Если ТЧ1Количество <> ТЧ2Количество Тогда
     ЗаписьЖурналаРегистрации(СтрокаСобытие, УровеньЖурналаРегистрации.Предупреждение, МетаданныеОбъекта, Объект.Ссылка, СтрокаСообщениеТабЧасть + ИмяТЧ + Символы.ВК + "Прежняя: " + Строка(ТЧ2Количество) + ". Новая: " + Строка(ТЧ1Количество));
    КонецЕсли;
    Если ТЧ1Количество = ТЧ2Количество Тогда
     СтрокаСообщение = СтрокаСообщениеРеквизит;
    ИначеЕсли ТЧ2Количество > ТЧ1Количество Тогда
     СтрокаСообщение = СтрокаСообщениеТабЧастьУдалено;
    ИначеЕсли ТЧ2Количество < ТЧ1Количество Тогда
     СтрокаСообщение = СтрокаСообщениеТабЧастьДобавлено;
    КонецЕсли;
    
    Для Инд = 0 По Макс(ТЧ1Количество - 1, ТЧ2Количество - 1) Цикл
     
     Для Каждого МДРТЧ ИЗ МДТЧ.Реквизиты Цикл
      Реквизит = МДРТЧ.Имя;
      
      // При необходимости проверку можно удалить
      Если НЕ ПроверяемыеРеквизитыТабЧасти.Свойство(Реквизит) Тогда
       Продолжить;
      КонецЕсли;
      
      Если Инд >= ТЧ1Количество Тогда
       НовыйРеквизитЗначение = Неопределено;
      Иначе
       НовыйРеквизитЗначение = ТЧ1[Инд][Реквизит];
      КонецЕсли;
      Если Инд >= ТЧ2Количество Тогда
       ПрежнийРеквизитЗначение = Неопределено;
      Иначе
       ПрежнийРеквизитЗначение = ТЧ2[Инд][Реквизит];
      КонецЕсли;
      
      Если (ЗначениеЗаполнено(ПрежнийРеквизитЗначение) И ЗначениеЗаполнено(НовыйРеквизитЗначение)) ИЛИ (НЕ ЗначениеЗаполнено(ПрежнийРеквизитЗначение) И ЗначениеЗаполнено(НовыйРеквизитЗначение)) ИЛИ (ЗначениеЗаполнено(ПрежнийРеквизитЗначение) И НЕ ЗначениеЗаполнено(НовыйРеквизитЗначение)) Тогда
       Если ТипЗнч(НовыйРеквизитЗначение) = Тип("Строка") Тогда
        НовыйРеквизитЗначение = СокрЛП(НовыйРеквизитЗначение);
       КонецЕсли;
       Если ТипЗнч(ПрежнийРеквизитЗначение) = Тип("Строка") Тогда
        ПрежнийРеквизитЗначение = СокрЛП(ПрежнийРеквизитЗначение);
       КонецЕсли;
       Если НовыйРеквизитЗначение <> ПрежнийРеквизитЗначение Тогда
        ЗаписьЖурналаРегистрации(СтрокаСобытие, УровеньЖурналаРегистрации.Предупреждение, МетаданныеОбъекта, Объект.Ссылка, СтрокаСообщение + ИмяТЧ + "." + Реквизит + " в строке " + (Инд + 1) + Символы.ВК + "Прежний: " + Строка(ПрежнийРеквизитЗначение) + Символы.ВК + "Новый: " + Строка(НовыйРеквизитЗначение));
       КонецЕсли;
      КонецЕсли;
      
     КонецЦикла;
    КонецЦикла;
   КонецЦикла;
  КонецЕсли;
  
 КонецЕсли;
 
КонецПроцедуры
К сожалению источник функции потерял.

Есть ли свойство 1С

// Универсальная функция для проверки наличия свойств у значения любого типа данных
// Переменные:
// 1. Переменная - переменная любого типа, для которой необходимо проверить наличие свойства
// 2. ИмяСвойства - переменная типа "Строка", содержащая искомое свойства
//
Функция СодержитСвойство(Переменная, ИмяСвойства) Экспорт // 14.10.2014 - Пермитин Ю.А.
     
    // Исключения. Эти типы не имеют свойств при проверке
    ТипПеременной = ТипЗнч(Переменная);
    Если ТипПеременной = Тип("Неопределено") ИЛИ ТипПеременной = Тип("Массив") Тогда
        Возврат Ложь;
    КонецЕсли;
     
    // Инициализируем структуру для теста с ключом (значение переменной "ИмяСвойства") и значением произвольного GUID'а
    GUIDПроверка = Новый УникальныйИдентификатор;
    СтруктураПроверка = Новый Структура;
    СтруктураПроверка.Вставить(ИмяСвойства, GUIDПроверка);
    // Заполняем созданную структуру из переданного значения переменной
    ЗаполнитьЗначенияСвойств(СтруктураПроверка, Переменная);
    // Если значение для свойства структуры осталось NULL, то искомое свойство не найдено, и наоборот.
    Если СтруктураПроверка[ИмяСвойства] = GUIDПроверка Тогда
        Возврат Ложь;
    Иначе
        Возврат Истина;
    КонецЕсли;
КонецФункции
Источник

15 окт. 2016 г.

Вывести диаграмму в две колонки 1С

Например, нужно вывести две диаграммы горизонтально.
Процедура Сформировать() 

 Результат.Очистить(); // Результат - это реквизит управляемой формы с типом ТабличныйДокумент
 Макет = РеквизитФормыВЗначение("Объект").ПолучитьМакет("Макет"); 
 
 Д1Макет = Д1(Макет); // в этой функции на выход будет ТабличныйДокумент с нарисованной первой диаграммой

 Д2Макет = Д2(Макет); // в этой функции на выход будет ТабличныйДокумент с нарисованной второй диаграммой
  
 Результат.Вывести(Д1Макет); 
 Результат.Присоединить(Д2Макет); 

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


Функция Д1(Макет)
    
    График = Макет.ПолучитьОбласть("Д1|Д1Г");
    
КонецФункции

Функция Д2(Макет)
    
    График = Макет.ПолучитьОбласть("Д2|Д2Г");

КонецФункции
Вся соль в том, что в макете, который мы получаем программно, а с макета области, где расположены "рисунки" диаграммы мы задаем имя не только горизонтальной области, а и вертикальной

и как раз при получении области мы указываем не только горизонтальную, а и вертикальную область
Макет.ПолучитьОбласть("Д2|Д2Г"); 
в итоге

29 сент. 2016 г.

RLS Объект не найден Отчеты

После применения RLS к Справочники.Подразделения, типовым отчетом решил глянуть Продажи по подразделениям и в результате получил много строчек "объект не найден"


в прочем это и логично, ведь мы запретили видеть некоторые Подразделения но не запретили их выводить (не отфильтровали) сами "отчеты", а точнее таблицы откуда берут данные отчеты, а это - регистры.

Значит открываю Регистры.Продажи, добавляю правило к Действию Чтения и пишу
Продажи ГДЕ Продажи.Подразделение В
 (ВЫБРАТЬ
 НастройкиПользователей.Значение
 ИЗ
 РегистрСведений.НастройкиПользователей КАК НастройкиПользователей
 ГДЕ
 НастройкиПользователей.Пользователь = &ТекущийПользователь
 И НастройкиПользователей.Настройка.Код = "00005")
Этим самым мы наложим фильтр через RLS, что бы видеть в результате отчет только
своих указаных в настройках пользователя Подразделения, а все другие данные по другим
подразделениям - фильтруем (отбрасываем)

Результат






RLS доступ к справочнику с иерархией элементов

Эта заметка продолжение ниже заметки.
Нужно конкретному пользователю в списке Справочники.Подразделения с иерархией элементов разрешить видеть только свои подразделения. Свои подразделения настраиваются в РегистреСведений.НастройкиПользователя.

Так как и ниже в заметке весь "секрет" ограничения заключается в том, что нужно сначала обращаться к Родителю, а потом к самому Элементу справочника, что бы пользователь при открытии Справочники.Подразделения мог видеть только разрешенные ему подразделения.

В настройке RLS в право на Чтение добавляем правило
Подразделения ГДЕ (Подразделения.Ссылка В
    (ВЫБРАТЬ
     НастройкиПользователей.Значение.Родитель
    ИЗ
     РегистрСведений.НастройкиПользователей КАК НастройкиПользователей
    ГДЕ
     НастройкиПользователей.Пользователь = &ТекущийПользователь
     И НастройкиПользователей.Настройка.Код = "00005")
   ИЛИ Подразделения.Ссылка В
    (ВЫБРАТЬ
     НастройкиПользователей.Значение
    ИЗ
     РегистрСведений.НастройкиПользователей КАК НастройкиПользователей
    ГДЕ
     НастройкиПользователей.Пользователь = &ТекущийПользователь
     И НастройкиПользователей.Настройка.Код = "00005"))
Результат

СправочникСписок.Отбор Иерархия элементов

Есть справочник Подразделение с иерархией элементов. Нужно при открытии этого справочника, в списке видеть только конкретный элемент иерархического справочника.

Вся суть "секрета" заключается в том, что нужно не только указывать в отборе списка элементов справочника элемент отбора, а и нужно указать в отборе Родителя отбираемого элемента.

  Список = Новый СписокЗначений;
  Список.Добавить(Справочники.Подразделения.НайтиПоКоду("000000002").Родитель);
  Список.Добавить(Справочники.Подразделения.НайтиПоКоду("000000002"));

  СправочникСписок.Отбор.Ссылка.Использование = Истина;
  СправочникСписок.Отбор.Ссылка.ВидСравнения = ВидСравнения.ВСписке;
  СправочникСписок.Отбор.Ссылка.Значение = Список;


вся соль вот в этой строчке

  Список.Добавить(Справочники.Подразделения.НайтиПоКоду("000000002").Родитель);

этим самым мы сначала пихаем в отбор Родителя, а потом и сам элемент, это все помещаем в списке значений так как вид сравнения будем использовать ВСписке

Результат


28 сент. 2016 г.

Есть ли Свойство в ЭлементыФормы

Например, нужно обойти все элементы формы и для тех элементов, в которых есть свойство Доступность установить значение в Ложь, а так же для тех элементов, в которых есть свойство ТолькоПросмотр также установить значение в Ложь.
Процедура ОбходВсехЭлементовФормы()
Для Каждого эл Из  ЭлементыФормы Цикл
                       
     Если эл.Имя = "ДействияФормы" Или эл.имя = "ОсновныеДействияФормы" Тогда 
              Продолжить;
    КонецЕсли;
                       
      Если ЕстьСвойство(эл, "ТолькоПросмотр") Тогда
             эл.ТолькоПросмотр = Ложь;
      ИначеЕсли ЕстьСвойство(эл, "Доступность") Тогда
            эл.Доступность = Ложь;
     КонецЕсли;

КонецЦикла;
КонецПроцедуры

Функция ЕстьСвойство(Объект, ИмяСвойства)
        РезультатФункции = Ложь;
        НачальноеЗНачение = Новый УникальныйИдентификатор();
        ЗначениеРеквизита = Новый Структура(ИмяСвойства, НачальноеЗНачение);
        ЗаполнитьЗначенияСвойств(ЗначениеРеквизита,Объект);
        Если ЗначениеРеквизита[ИмяСвойства] <> НачальноеЗНачение Тогда
                РезультатФункции = Истина;
        КонецЕсли;
        Возврат РезультатФункции;
КонецФункции
или через попытку
Попытка
    Рек.Доступность = Ложь;
Исключение
КонецПопытки;
Способы нашел на просторах интернета.

20 сент. 2016 г.

Установить курсор на конкретную строку таблицы значений

Элементерно, но все же, например, нужно установить в Таблице значений управляемых формах курсор (активность) на последнюю строку

Элементы.СтрокиВыпускПродукции.ТекущаяСтрока =
ЭтаФорма.СтрокиВыпускПродукции.Получить(СтрокиВыпускПродукции.Количество()-1).ПолучитьИдентификатор();

19 сент. 2016 г.

Из Com объекта в таблицу значений

На вход передаем Com объект, на выходе будем иметь ТаблицуЗначений с наименованием колонок аналогично свойствам Com объекта + заполнена ТаблицаЗначений данными с Com объекта.
Функция ИзComВТаблицуЗначений(Com)
 //Перемещаем указатель на первую запись.
 Com.MoveFirst(); 
 
 Таблица = Новый ТаблицаЗначений; 
 ОдинРаз = Неопределено;
 
 //Начинаем перебор записей из субд
 Пока Com.EOF() = 0 Цикл
  
  //Заполним колонки
  Если ОдинРаз = Неопределено Тогда 
   Для Каждого Значение Из Com.Fields Цикл 
    Таблица.Колонки.Добавить(Значение.Name);
   КонецЦикла; 
   ОдинРаз = Истина;
  КонецЕсли;
  
  //Заполняем таблицу значений
  НовСтрока = Таблица.Добавить();
  Для Каждого Колонка Из Таблица.Колонки Цикл 
   Для Каждого Значение Из Com.Fields Цикл 
    Если Колонка.Имя = Значение.Name Тогда 
     НовСтрока[Колонка.Имя] = Значение.Value;
    КонецЕсли;    
   КонецЦикла;
  КонецЦикла;
  
  // Перемещаем указатель.
  Com.MoveNext();    
 КонецЦикла;    
 Возврат Таблица
КонецФункции

Очистка таблицы значений от ненужных строк

//Очистка ТЗ от ненужных строк, алгоритм Эльниньо

 ТЗ.ВыбратьСтроки();
 Пока ТЗ.ПолучитьСтроку() = 1 Цикл 
  
     Пока ТЗ.ЧтоТо = Ненужное Цикл
          ТЗ.УдалитьСтроку();
          Если ТЗ.НомерСтроки = 0 Тогда Прервать; КонецЕсли;
  КонецЦикла;

 КонецЦикла;

Правильное удаление строк из таблицы значений

//******************************************************************************
// ОчисткаТЗ()
// Параметры: ТЗ, которую надо очистить
// В ТЗ д.б. Колонки с идентификаторами "НадоУдалить" и "ОПС" (оригинальный порядок строк)
// Описание: очищает ТЗ от ненужных строк
Процедура глОчисткаТЗ(ТЗдляЧистки, ОПС="+ОПС", КолонкаУдалить="НадоУдалить", Режим=0) Экспорт
 
 Попытка  НадоУдалить = ТЗдляЧистки.Итог(КолонкаУдалить);
 Исключение Возврат;
 КонецПопытки;
 
 ТЗКС = ТЗдляЧистки.КоличествоСтрок();
 Если Режим <> 0 Тогда
  Сообщить("> ["+ТекущееВремя()+"]: *** удаляем "+НадоУдалить+" из "+ТЗКС+" ****"); 
 КонецЕсли;
 
 Если НадоУдалить <= 0 Тогда Возврат; КонецЕсли;
 
 Если НадоУдалить >= ТЗКС Тогда
  ТЗдляЧистки.УдалитьСтроки();
 Иначе
  ТЗРаб = СоздатьОбъект("ТаблицаЗначений"); ТЗдляЧистки.Выгрузить(ТЗРаб);
  ТЗРаб.Сортировать("+"+КолонкаУдалить); ТЗРаб.Выгрузить(ТЗдляЧистки,1,ТЗКС-НадоУдалить);
  ТЗРаб = 0;
 КонецЕсли;
 Если ПустаяСтрока(ОПС) = 1 Тогда Возврат; КонецЕсли; //сортировать не надо
 Если ОПС = "###" Тогда Возврат; КонецЕсли; //сортировать не надо
 //восстановим оригинальный порядок строк
 ТЗдляЧистки.Сортировать(ОПС);
КонецПроцедуры //глОчисткаТЗ()
 

CopyPaste Copyright © 2017 - |- Шаблон создан O Pregador - |- Отредактирован myr4ik07