Суббота, 26.07.2025, 22:01

Главная
Примочки к 1С
Ссылки на 1С ресурсы
  • Специалист
  • Клуб професионалов 1С
  • Статистика
    Главная » FAQ » 2 [ Добавить вопрос ]


    // Присвоить значение переменной по ее имени.
    // в глоб.модуль:
    Функция Присвоить(Чему,Что) Экспорт
          Чему = Что;
          Возврат "";
    КонецФункции
    // варианты вызова:
    // Шаблон("[Присвоить("+ИмяПеременной+",ПеременнаяСоЗначением)]");
    // Шаблон("[Присвоить("+ИмяПеременной+","+ИмяПеременнойСоЗначением+")]");
    // Пример: пусть у нас на форме есть 5 числовых реквизитов К1, К2, ... К5
    Для н=1 по 5 Цикл
      Шаблон("[Присвоить("+("К"+н)+","+(н)+")]");
    КонецЦикла;

    Если в качестве параметров ф-ии Присвоить() могут передаваться ТаблицаЗначений или СписокЗначений, то нужно её изменить на:
    Функция Присвоить(Чему,Что)
      Если Найти(ТипЗначенияСтр(Что),"Значений")>0 Тогда
      Чему=СоздатьОбъект(ТипЗначенияСтр(Что));
      Что.Выгрузить(Чему);
      Иначе
      Чему = Что;
      КонецЕсли;
      Возврат "";
    КонецФункции


    В глобальном модуле доступны все переменные, функции и реквизиты вызывающей формы! 
    При этом даже не требуется передавать Контекст формы!
    Пример: 
    // помещаем в глобальный модуль процедуру
    //_____________________________________________________________________________
    Процедура глТест() Экспорт
      сообщить(Шаблон("[ПеременнаяМодуля]")); // получаем переменную модуля
      сообщить(Шаблон("[РеквизитФормы]")); // получаем переменную модуля формы 
      сообщить(Шаблон("[ФункцияМодуля()]")); // вызываем функцию модуля формы 
    КонецПроцедуры //глТест()  

    // создадим внешнюю обработку
    // не забудьте добавить на форму реквизит "РеквизитФормы" тип "Строка",30
    // текст модуля внешней обработки:
    Перем ПеременнаяМодуля;
    //_____________________________________________________________________________
    Функция ФункцияМодуля()
      Сообщить("Сработала функция модуля");
    КонецФункции 
    //_____________________________________________________________________________
    Процедура Сформировать()
      глТест(); // вызываем глоб процедуру и смотрим ...
    КонецПроцедуры
    //_____________________________________________________________________________
    ПеременнаяМодуля="Это значение ПеременнойМодуля";
    РеквизитФормы="Это значение РеквизитаФормы";


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

    В модуле делаем процедуру:

    Процедура Сообщить(Текст,Флаг = "")

         Если Константа.Авто = 1 Тогда

                   ДобавитьТекстВФайл(Текст,Флаг);
         Иначе
               Message(Текст,Флаг);
      КонецЕсли;
    КонецПроцедуры

    Заметьте, что для вызова "родной" процедуры нужно использовать другой язык. Это еще одна хитрость в этом методе.


    Примечание: такое переопределение работает только в локальном контексте и только в той части модуля, которая стоит после переопределения. Хотя можно переопределить и на весь модуль, если воспользоваться объявлением "Далее".


    Процедура ПриРедактированииНовойСтроки()
         Если Товар.Выбран()=1 тогда
         Сообщить("Скопировали строку");
         КонецЕсли;
    КонецПроцедуры

    В запросе, где есть группировка Месяц, после выполнения возвращается Запрос.Месяц, например, = "Июль 02". Чтобы сконвертировать" в формат "01.07.02" воспользуемся недокументированным методом Запрос.ЗначениеГруппировки("Месяц")). Метод вернет дату начала месяца в формате даты, т.е. вида 'дд.мм.гг'.
     Пример:
    //*******************************************
    // НачДата, КонДата - реквизиты формы типа "Дата"
    //*******************************************
    Процедура Сформировать()
      ТЗ = "
      |С НачДата по КонДата;
      |Группировка Месяц Все;";
      Запрос = СОздатьОбъект("Запрос");
      Если Запрос.Выполнить(ТЗ) = 0 Тогда
      Возврат;
      КонецЕсли;
      Пока Запрос.Группировка(1) = 1 Цикл
      Сообщить("Запрос.Месяц = "+Запрос.Месяц);
      Сообщить(" = "+Запрос.ЗначениеГруппировки("Месяц"));
      КонецЦикла;
    КонецПроцедуры
    //*******************************************

    Результат работы такой:
    Запрос.Месяц = Январь 02
    = 01.01.02
    Запрос.Месяц = Февраль 02
    = 01.02.02
    Запрос.Месяц = Март 02
    = 01.03.02
    Запрос.Месяц = Апрель 02
    = 01.04.02
    Запрос.Месяц = Май 02
    = 01.05.02
    Запрос.Месяц = Июнь 02
    = 01.06.02
    Запрос.Месяц = Июль 02
    = 01.07.02
    Запрос.Месяц = Август 02
    = 01.08.02

    Известно, что Активизировать() и АктивизироватьОбъект() не работает в процедуре, вызываемой из формулы реквизита,
    а работает только в предопределенных процедурах. Это, непонятно для чего введённое, ограничение можно обойти.
    К примеру, такая задача:

    Есть текстовое поле ввода на форме, в которое вручную или со сканера вводится штрихкод. Для удобства оператора, требуется вводить код номенклатуры сканером без участия клавиатуры -
    чтобы не надо было каждый раз возвращаться назад на этот реквизит.
    Можно воспользоваться следующим кодом:

    Перем МожноЗакрыть;
    //******************************************************************************
    // 
    Процедура ПриЗакрытии()
         Если МожноЗакрыть=0 тогда
              Активизировать("Код");
              СтатусВозврата(0);
         КонецЕсли;            
         
    МожноЗакрыть=1;
    КонецПроцедуры
     // ПриЗакрытии
    //******************************************************************************
    // вызов этой процедуры осуществляем из формулы нужного реквизита
    Процедура ПриВводеКода()
         Если ПустоеЗначение(Код)=0 Тогда
              // здесь получаем введенный штрихкод
              Код=""; // очищаем поле
              
    МожноЗакрыть=0;
              Форма.Закрыть(0);
         КонецЕсли;
    КонецПроцедуры
     // ПриВводеКода
    //*******************************************
    МожноЗакрыть=1;


    [ИТС:Методическая поддержка 1С:Предприятия 7.7] >>> [Особенности использования формул полей ввода диалогов форм] - последний абзац:
    > Если в формуле поля ввода выполняется обращение к функции, вызывающее появление _м_о_д_а_л_ь_н_о_г_о_ /* выделено мной */
    > окна (например, вызов функции "Предупреждение" или "Вопрос"), то после закрытия модального окна
    > активным остается то поле, формула которого выполнялась.

    Можно обойтись и без показа модальной формы. Для этого, в процедуре проверки, вызываемой из формулы реквизита, добавляем вызов модального открытия любой формы. В модуле же формы пишем всего одну строку:

    Процедура
     ПриОткрытии() СтатусВозврата(0) КонецПроцедуры


    Эффект будет таким же как и выше, т.е. фокус ввода останется на том же самом реквизите.
    Например, для внешней обработки применение этой фичи возможно следующим образом:

    Процедура ПриОткрытии()
         Если форма.параметр="НеИзменятьФокусВвода" тогда
              СтатусВозврата(0); возврат;
         КонецЕсли;
         // дальше "родной" код
    КонецПроцедуры


    Если значение какого-нибудь реквизита формы не подходит под условия, делаем вызов:

    ОткрытьФормуМодально("Отчет#","НеИзменятьФокусВвода",РасположениеФайла());

    Аналогичным образом можно воспользоваться этим и для других форм.
    Лично мне это было нужно в случае именно ввода НОВЫХ элементов справочников, НОВЫХ документов,
    и ОСОБЕННО(!!!) - при вводе НОВЫХ СТРОК в документе... при проверке значения, введенного в очередную колонку НОВОЙ строки документа.

    Воспользуйтесь след.кодом:
    О=СоздатьОбъект("Операция");
    О.Новая();
    О.ДатаОперации=ДатаОперации; // здесь нужная дата
    О.Содержание=СодержаниеОперации;
    Если
     ДатаГод(О.ДатаОперации) <> ДатаГод(РабочаяДата()) Тогда
         О.Документ.УстановитьНовыйНомер("");
    КонецЕсли;

    // Заводим общий реквизит документов "ВидДокументаКлиент"
    // В Глобальном модуле. 
    Функция ПолучитьВнутрКод(Клиент) Экспорт
         СписокЗн = СоздатьОбъект("СписокЗначений");
         СписокЗн.ИзСтрокиСРазделителями(ЗначениеВСтрокуВнутр(Клиент));
         ИД = СписокЗн.ПолучитьЗначение(7);
         Возврат Сред(ИД,2,9);
    КонецФункции
    // Вызывается из документов ПриЗаписи()
    Процедура глУстановитьРеквизитыОтбора(Конт) Экспорт
         Конт.ВидДокументаКлиент=Конт.Вид();
         Если глЕстьРеквизитШапки("Клиент",Конт.Вид()) = Да Тогда
              Если ПустоеЗначение(Конт.Клиент) = 0 Тогда
                   Конт.ВидДокументаКлиент = СокрЛП(Конт.Вид())+СокрЛП(ПолучитьВнутрКод(Конт.Клиент));
              КонецЕсли;
         КонецЕсли;
    КонецПроцедуры
    // В журнале
    УстановитьОтбор("ВидДокументаКлиент",ВыбВидДокумента.ПолучитьЗначение(ТС)+СокрЛП(ПолучитьВнутрКод(ВыбКлиент)));


    // Вызов процедуры на примере документа.
    // модуль формы документа
    Процедура ПриОткрытии()
         Если ТипЗначенияСтр(Форма.Параметр)="СписокЗначений" тогда
              СЗ=Форма.Параметр;                        
              
    Команда=СЗ.Получить("Команда");
              Если "Печать"=Команда тогда  
                   
    Печать();  
                   
    СтатусВозврата(0);
                   Возврат;
              КонецЕсли;     
         
    КонецЕсли;     
    КонецПроцедуры
    // Сам вызов (из любого места конфигурации):
    СЗ=СоздатьОбъект("СписокЗначений");
    СЗ.ДобавитьЗначение("Печать","Команда");
    ОткрытьФормуМодально(
    Док.ТекущийДокумент(),СЗ);

    Copyright MyCorp © 2025