О формах 1С замолвите слово... Необычное использование знакомого всем объекта

13.01.21

Разработка - Механизмы платформы 1С

Неочевидно, но форму 1С можно использовать как универсальный объект, который доступен на клиенте и имеет уникальный набор свойств, методов, событий и конструктор, принимающий параметры. При этом у формы может не быть интерфейса, и ее можно даже не открывать. О реальных примерах применения такого подхода пойдет рассказ.

 

Что такое объект

 

 

Форма – это, в принципе, объект, некая изолированная логически сущность, у которой есть:

  • свойства, описывающие состояние;

  • методы, описывающие поведение этой сущности;

  • и события для реагирования на какие-то сообщения от других внешних объектов.

Все объекты относятся к какому-то классу.

В 1С используется не чистое объектно-ориентированное программирование, но объекты здесь тоже есть:

  • в дереве метаданных конфигурации каждая ветка представляет собой набор объектов.

  • «Обработки» я выделил на слайде справа как универсальный объект, который используется для решения общих задач, потому что он не привязан к каким-то конкретным объектам базы данных – это отдельная логическая сущность.

 

Универсальные объекты в 1С

 

 

В 1С у нас есть два универсальных объекта – это обработка и форма.

Обработка есть только на сервере. Ее никак нельзя создать на клиенте, с ней можно работать только на сервере. У нее есть:

  • свойства – реквизиты, переменные;

  • методы, которые можно описать в модуле объекта;

  • событий у нее нет (она не может обрабатывать события);

  • и конструктора у нее тоже отдельного нет – если нужно как-то проинициализировать новый объект, нужно писать отдельную процедуру с параметрами.

Это все только на сервере. А если нужно такое на клиенте? Для этого есть форма.

Форма – это такой же объект, имеющий:

  • свойства – реквизиты, переменные;

  • методы;

  • также у нее есть события в виде обработчиков;

  • и конструктор «ПриСозданииНаСервере», где можно передать параметры.

Странно, что я говорю, что форма существует на клиенте, но при этом у нее есть конструктор «ПриСозданииНаСервере». Да, это такая двойственная сущность форм, что они одновременно есть и на клиенте, и на сервере. Чуть позже коснемся этого подробнее.

 

Методы формы

 

 

Отдельно о методах формы.

Здесь я создал форму и в модуле написал все варианты методов – НаКлиенте, НаСервере, НаСервереБезКонтекста и НаКлиентеНаСервереБезКонтекста:

  • каждый из этих методов представлен здесь в публичном и приватном варианте (объявленный с ключевым словом Экспорт или без него);

  • внутри каждого метода я для проверки просто пишу «Сообщить(ИмяМетода);»;

  • в самом низу в коде модуля (вне процедур, вне методов) тоже пишу «Сообщить(«КодМодуля»);»;

  • еще один момент, если можете заметить – внизу два раза объявлен метод «ПриватныйМетодНаКлиентеНаСервереБезКонтекста» с абсолютно одинаковым именем, и это не будет ошибкой. Это давно известная проблема на уровне платформы, которую почему-то все никак не решают – это просто нужно иметь в виду.

И в качестве теста мы создаем новую форму методом ПолучитьФорму и далее в попытке вызываем каждый из этих методов. Сразу как ложка дегтя – контекстная подсказка не работает, платформа 1С сама в шоке, что такое можно делать, она ничего не подсказывает.

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

  • первым делом сработал код модуля на сервере;

  • потом отработал обработчик «ПриСозданииНаСервере»;

  • обработчик «ПриОткрытии» не отработал, потому что форму я не открывал;

  • потом идет код модуля на клиенте;

  • потом – публичный метод;

  • и потом ряд методов на сервере - контекстные методы отрабатывают с кодом модуля на сервере, а бесконтекстные методы не вызывают код модуля.

Какие можно сделать из этого выводы:

  • во-первых, очевидно, что в коде модуля формы ничего писать не стоит, потому что это будет вызываться каждый раз при вызове каждого контекстного метода и отрабатывать как на сервере, так и на клиенте;

  • также видно, что никак не вызвать экспортный метод, объявленный с директивой «НаКлиентеНаСервереБезКонтекста»;

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

 

 

Здесь на слайде показана пояснительная диаграмма – как можно между собой выстроить взаимосвязь вызовов на разных директивах.

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

Исключение – бесконтекстные методы. Они могут вызывать друг друга.

 

Реквизиты и переменные формы

 

 

Теперь о полях формы – какие они бывают, какое у них поведение, как их можно использовать. На форме, которая показана на слайде, у нас есть

  • один реквизит числового типа;

  • и в модуле я объявляю две переменные «Клиент» и «Сервер» (на клиенте и на сервере соответственно).

И дальше буду вызывать методы, которые будут работать с переменными.

Вначале эти переменные будут не инициализированы (будут иметь значение Неопределено), и потом я их буду либо инициализировать, либо просто прибавлять единицу. И посмотрим, что будет происходить.

  • В процедуре «ПриСозданииНаСервере» я два раза вызываю «МетодНаСервере»:

    • значение «Реквизита» у нас сразу же увеличивается и уже никуда не теряется;

    • а серверная переменная сначала была нулевая (она проинициализировась), потом ее вызвали еще раз – она увеличилась, все нормально.

  • Попали на клиент, вызвали «ПубличныйМетодНаКлиенте»:

    • «Реквизит» дальше везде будет сохраняться и просто увеличиваться;

    • переменную «Клиент» инициализировали, а потом увеличили;

    • вызываем «МетодНаСервере» – серверная переменная равна нулю (при переходе с сервера на клиент ее значение потерялось);

    • опять вызываем «МетодНаСервере» – серверная переменная опять нулевая, потому что теряем эту переменную при переходе;

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

Какие можно сделать выводы:

  • реквизиты хранятся всегда и доступны как на клиенте, так и на сервере;

  • переменные на клиенте доступны только на клиенте;

  • переменные на сервере хранятся только во время серверного вызова, пока мы не ушли на клиент;

  • но в реквизитах нельзя хранить все типы данных – это только данные, которые можно определить на форме, которые могут свободно гулять между клиентом и сервером (в то время как в переменных на клиенте можно хранить любые типы объектов, которые доступны на клиенте).

Соответственно, если нужно работать с чем-то простым и на сервере, и на клиенте, то можно использовать реквизиты – они будут доступны везде. А для работы с объектами сложного типа на стороне клиента удобно использовать клиентские переменные.

 

Обработчики событий

 

 

Еще у форм 1С есть обработчики событий – их работу здесь демонстрирует немного странный, но показательный пример.

Считаем, что у нас есть отдельная специальная общая форма «СуммаКвадратов», которая умеет вычислять сумму квадратов. У нее есть:

  • табличная часть, где определяются слагаемые и для каждого слагаемого указывается признак, что оно было возведено в квадрат (реквизит «Возведено» с типом «Булево»);

  • и есть экспортный метод «ВычислитьСумму()» – считаем, что этот метод умеет только складывать, а в квадрат он возводить не умеет, поэтому для каждого слагаемого ему придется вызвать отдельную общую форму «Квадрат», которая возводит в квадрат. И вот мы создаем отдельную форму «Квадрат» и для каждого слагаемого посылаем оповещение «ВозвестиВКвадрат».

В форме «Квадрат»:

  • получаем оповещение с именем события «ВозвестиВКвадрат» и, если параметр «Возведено» не установлен, число перемножается само на себя, и возвращает параметр «Возведено» в значении «Истина»;

  • после этого оповещение «ВозведеноВКвадрат» передается обратно в источник.

Возвращаемся назад в форму «СуммаКвадратов»:

  • здесь в обработке оповещения для события «ВозведеноВКвадрат» мы проверяем, что каждой строчке таблицы слагаемых установлен признак «Возведено», и если все слагаемые возведены в квадрат, то сообщаем сумму итога по таблице.

Справа на слайде показан пример вызова – создаем форму «СуммаКвадратов», задаем слагаемые и вызываем метод «ВычислитьСумму».

В результате вызова видим ответ «Сумма = 14», значит, все считается верно.

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

 

Примеры использования форм

 

 

Далее переходим от теории к практике. Где вообще это можно использовать?

Здесь я перечислил примеры, которые встречаются в типовых и отраслевых конфигурациях именно как такое использование форм через вызов ее методов. Обычно это работа с какими-то внешними системами, внешними объектами, оборудованием – такими как:

  • телефония;

  • почтовые клиенты;

  • электронный документооборот;

  • а также всем знакомый механизм «ВызовКлиентскогоМетода» из подсистемы «Дополнительные отчеты и обработки» БСП.

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

 

Форма как заменитель объекта

 

 

Дальше я покажу пример использования формы как заменителя объекта, который я использовал при мобильной разработке.

У меня было приложение с использованием функций фотографирования.

Для работы с камерой в 1С:

  • у объекта «СредстваМультимедиа» есть платформенный метод «СделатьФотоснимок», который после фотографирования возвращает типовой 1С-ный объект с типом «ДанныеМультимедиа»;

  • этот возвращаемый объект имеет свойства «РасширениеФайла» и «ТипСодержимого», а также метод «ПолучитьДвоичныеДанные», чтобы дальше работать с двоичными данными этого снимка.

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

Поэтому в качестве альтернативного варианта я рассмотрел метод Android ImageCapture, позволяющий вызывать для фотографирования внешние приложения (с помощью этого метода можно вызвать типовую камеру, либо какое-то другое приложение камеры, которое установлена в телефоне).

Однако этот метод Android, конечно же, возвращает не «ДанныеМультимедиа» от 1С, а имя файла, поэтому просто так заменить один метод на другой не получится (теперь в каждом куске кода уже нужно обрабатывать, откуда пришел этот снимок и забирать эти данные уже оттуда).

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

  • экспортные клиентские переменные «РасширениеФайла» и «ТипСодержимого»,

  • а также приватную переменную «ДвоичныеДанные», в которой хранится сам снимок,

  • и экспортный метод «ПолучитьДвоичныеДанные()».

Теперь у меня в процессе фотографирования в качестве объекта «ДанныеМультимедиа» возвращалась эта форма, и полученные от нее данные шли в остальное приложение, которое работало, как и раньше, не замечая подмены – я спокойно использовал эту форму как другой объект 1С.

 

Модули прикладных объектов

 

 

Дальше рассмотрим, как можно использовать модуль формы как модуль прикладных объектов.

У каждого прикладного объекта, будь то справочник, документ и т.д. есть стандартные модули (модуль самого объекта для работы с конкретным объектом и модуль менеджера для работы с группой объектов или классом в целом), но они доступны только на сервере и вызвать их можно только с сервера.

Чтобы вызывать какие-то методы на клиенте для работы со ссылками и т.д. обычно создаются отдельные общие модули с различной комбинацией флагов «ВызовСервера», «Клиент», «Сервер» (в варианте КлиентСервер), что выглядит несколько странно, неудобно – как будто один объект разорван по дереву конфигурации.

Что можно сделать? Можно использовать специальную форму, которая будет внутри этого прикладного объекта. Назвать ее, допустим, «МодулиНаКлиенте», и все эти модули перенести туда, потому что там внутри можно делать и серверные, и клиентские варианты вызовов.

Это дает преимущества:

  • не нужны отдельные модули – все находится в одном месте;

  • можно даже переносить решение между конфигурациями, если используется какой-то независимый прикладной объект. Он просто копируется и все методы объекта пойдут вместе с ним;

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

И, как пример, что такое есть в типовых конфигурациях, справа показана обработка «ДокументооборотСКонтролирующимиОрганами». Вообще это, конечно, монстроидальный объект, потому что и в самом модуле объекта, и в форме «КонтейнерКлиентскихМетодов», по 60 000 строк, тысяча методов, сама эта обработка содержит 50 - 60 форм, но, тем не менее, одна из форм в ней используется для вызова методов на клиенте.

 

Работа с данными на клиенте

 

 

На слайде показан пример, который вызывает реакцию: «А что, это вообще законно?» Это – работа с данными базы на клиенте. Допустим, у нас есть заказ клиента, и мы хотим сделать диверсию: подменить партнера на своего знакомого и поделить все цены пополам. Мы в процедуре на клиенте:

  • создаем форму документа «ЗаказКлиента» методом «ПолучитьФорму»;

  • передаем в качестве ключа ссылку на заказ;

  • и дальше работаем со значением его реквизита «Объект, как с обычным объектом на сервере: заменяем партнера, поменяем цены в табличной части и в конце вызываем метод формы «Записать()».

Конечно, было бы обманом говорить, что все это делается только на клиенте, без сервера. По крайней мере, здесь есть два серверных вызова:

  • при создании формы – чтение ее данных;

  • при записи – запись на сервер.

Тем не менее, сам код написан на клиенте.

И в качестве совета – здесь я использую стандартную типовую форму объекта, но это будет, конечно, не очень оптимально, потому что там при создании на сервере отрабатывает очень много кода по обработке кучи элементов. Правильнее для работы с данными создавать отдельную пустую форму – главное, чтобы на ней в качестве основного реквизита использовался конкретный объект метаданных (в данном случае, «ЗаказКлиента»).

 

Взаимодействие открытых баз по протоколу UDP

 

 

И последний пример, о котором хочется рассказать подробнее (мы это в свое время мы делали в компании Юг-Авто) – это взаимодействие открытых баз.

Представьте, что у вас на предприятии используется несколько учетных систем. Например, вся работа с клиентами, первичная документация ведется в «Управлении торговлей», а бизнес-процессы, общение сотрудников, исполнительская деятельность по сотрудникам – в отдельной базе с «1С:Документооборот»:

  • пользователь работает за своим компьютером, у него открыто обе базы – он смотрит заказ клиента в «Управлении торговлей» и ему нужно поставить задачу какому-то сотруднику по этому заказу в «1С:Документообороте» – для этого в форме заказа есть кнопка «Создать бизнес-процесс»;

  • пользователь нажимает эту кнопку, и ему тут же в окне запущенного «Документооборота» открывается форма исполнения, куда уже был перенесен заказ клиента из другой базы – он заполняет в этой форме все необходимое (описание, что нужно сделать и исполнителя) и стартует бизнес-процесс;

  • исполнитель получает задачу и видит опять же заказ клиента в виде ссылки в этой форме задачи – нажимает на эту ссылку и ему уже, наоборот, открывается «Управление торговлей», где он видит этот заказ.

Получается, что, не делая обычный обмен между базами, можно на клиенте все равно предметно вести бизнес-процессы по каким-то объектам из другой базы.

 

 

Основа этого подхода – протокол UDP. Это довольно старый протокол, который был изобретен еще в начале 80-х годов, он расшифровывается как «Протокол пользовательских датаграмм». Довольно простой протокол, но не очень широко известен среди разработчиков 1С. Поэтому чтобы лучше его объяснить, я написал сравнение UDP и более знакомого 1С-никам HTTP на основе TCP.

В чем их разница:

  • UDP проще, у него нет подтверждения связи – мы просто отправляем сообщение, и точно не знаем, дошло оно или нет, а в TCP нужно создать отдельный канал (он передает данные только по каналу), ему нужно подтверждение и т.д.;

  • UDP более легковесный – меньше передает данных туда-обратно, не требует предварительной установки соединения и т.д.;

  • в UDP может быть широковещательная передача (всем одновременно), а в TCP – это всегда общение по конкретному созданному каналу

  • для передачи по протоколу UDP не нужна публикация на веб-сервере (это удобно технически со стороны 1С), а чтобы база принимала данные по HTTP, ее нужно обязательно опубликовать на веб-сервере.

Где можно применить UDP:

  • для связи 1С с другими запущенными программами – дальше я расскажу про пример с 1С, но можно применить UDP для связи не только с 1С – можно организовать общение с любыми программами, если на принимающей стороне также организовать работу по UDP;

  • причем можно организовать общение между программами не только на одном компьютере, но и можно передавать сообщения между разными компьютерами сети;

  • и можно передавать данные с сервера на клиент – если на сервере есть возможность обрабатывать протокол UDP, то можно наоборот, передавать данные именно с сервера на клиент (хотя обычно в 1С это делать нельзя). С помощью этого можно сделать прогресс-бар при долгих задачах на сервере, какие-то еще оповещения о завершении и т.д.

 

 

Какие особенности конкретно у этого алгоритма взаимодействия:

  • конечно, используется внешняя компонента, потому что в 1С нет встроенных механизмов для работы по UDP;

  • основная логика описана в модуле формы – в каждой базе есть форма, которая отвечает за этот механизм;

  • чтобы передать данные по UDP, нужно знать адрес и порт, на который передать эти данные (у каждой базы должен быть зафиксирован какой-то конкретный номер порта – мы открываем базу и начинаем слушать входящие сообщения на конкретном порте).

Допустим, нам нужно создать бизнес-процесс исполнения из «Управления торговлей» в «Документообороте». Для этого мы вызываем метод «ОтправитьКоманду»:

  • в нем методом SendTo компоненты UDPTor отправляем команду на заданный номер порта с адресом (по умолчанию в качестве адреса используется 127.0.0.1 – это localhost, потому что мы работаем на одном компьютере) – например, отправили команду «Создать бизнес-процесс исполнения по такому-то заказу клиента»;

  • по умолчанию задаем, что «ПришелОтвет = Ложь» (мы пока не уверены, что пришел ответ);

  • ждем одну секунду с помощью обработчика ожидания «ПроверитьПолучениеКоманды» – данные пошли;

  • обратно я нарисовал штриховую стрелку, потому что данные могут не вернуться (например, база «Документооборота» у пользователя в данном случае сейчас не открыта), но если база была открыта, то происходит обработка внешнего события «Server» от источника «UdptorChat» – если другая база прислала ответ, что она получила команду, то записываем в переменную «ПришелОтвет = Истина» и успокаиваемся;

  • а через секунду по обработчику ожидания смотрим – если ответ от открытой базы не пришел (а за секунду он точно должен был уже прийти, если база была включена), то дальше мы уже сами запускаем базу с параметрами.

По сути, параметры – это то же самое, что и команда. И тогда, если у пользователя база не открыта, то она сначала запускается, и потом уже в ней сразу открывается форма создания бизнес-процесса.

В данном примере используется компонента из публикации //infostart.ru/public/69992/. Это довольно старая публикация, после нее на Инфостарте появлялись еще и другие решения по работе с UDP, так что, если вас это заинтересует, можете выбрать, что вам по вкусу.

 

Вопросы:

 

  • Меня интересует общение между базами 1С, установленными на разных компьютерах. Например, у нас есть две базы – «1С:Документооборот и 1С:Управление торговлей», у каждой из которых запущена внешняя компонента. Это работает не только на одном компьютере, но и в локальной сети?

  • Да, как я говорил, при отправке сообщения есть параметр «Адрес» – и это может быть адрес в локальной сети или какой-то другой адрес.

  • Правильно ли я понимаю, что, если мы на каждый компьютер в нашей компании установим эту компоненту и захотим создать свой чат в локальной сети, то один человек пишет сообщение в этом чате, нажимает кнопку и благодаря выполнению всего лишь одной строчки кода всем одновременно в тот же чат отправляется одно и то же сообщение. По сути – это может быть заменой системы взаимодействия от 1С?

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

  • Получается, что это – способ общения между разными формами разных конфигураций. Причем, в этом пакете мы можем посылать не только текстовую информацию. Мы можем пересылать ссылки. И если эта ссылка есть в конфигурации-приемнике, она ее нормально распознает как объект и сделает с ним определенные действия. Это действительно какая-то магия. Что это за компонента – она бесплатная, она работает на 64-бита или только на 32?

  • Конкретно это компонента довольно старая, она бесплатная и работает только под 32 бита, но есть и другие решения, построенные по технологии NativeAPI – они должны работать везде, в том числе кроссплатформенно.

 

*************

Данная статья написана по итогам доклада (видео), прочитанного на INFOSTART MEETUP Krasnodar.

 

30 мая - 1 июня 2024 года состоится конференция Анализ & Управление в ИТ-проектах, на которой прозвучит 130+ докладов.

Темы конференции:

  • Программная инженерия.
  • Инструментарий аналитика.
  • Решения 1С: архитектура, учет и кейсы автоматизации на 1С.
  • Управление проектом.
  • Управление продуктом.
  • Soft skills, управление командой проекта.

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

Подробнее о конференции.

 


См. также

Поинтегрируем: сервисы интеграции – новый стандарт или просто коннектор?

Обмен между базами 1C Администрирование СУБД Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

В платформе 8.3.17 появился замечательный механизм «Сервисы интеграции». Многие считают, что это просто коннектор 1С:Шины. Так ли это?

11.03.2024    4481    dsdred    53    

71

Как готовить и есть массивы

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Все мы используем массивы в своем коде. Это один из первых объектов, который дают ученикам при прохождении обучения программированию. Но умеем ли мы ими пользоваться? В этой статье я хочу показать все методы массива, а также некоторые фишки в работе с массивами.

24.01.2024    5282    YA_418728146    25    

63

Планы обмена VS История данных

Обмен между базами 1C Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    6401    dsdred    36    

111

1С-ная магия

Механизмы платформы 1С Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    18466    SeiOkami    46    

118

Дефрагментация и реиндексация после перехода на платформу 8.3.22

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    12082    human_new    27    

74

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    8803    YA_418728146    6    

141

Внешние компоненты Native API на языке Rust - Просто!

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Внешние компоненты для 1С можно разработывать очень просто, пользуясь всеми преимуществами языка Rust - от безопасности и кроссплатформенности до удобного менеджера библиотек.

20.08.2023    6273    sebekerga    54    

94

Все скопируем и вставим! (Буфер обмена в 1С 8.3.24)

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Рассмотрим новую возможность 8.3.24 и как её можно эффективно использовать

27.06.2023    15974    SeiOkami    31    

103
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. markers 274 13.01.21 18:03 Сейчас в теме
За публикацию спасибо, но не раскрыта тема типа реквизита "Произвольный", который позволяет использовать Фиксированные значения (Массив, Соответствие, Структура) и может даже ещё чего. Чего порой очень не хватает, когда клиент достаточно "самостоятелен". Так же появляется возможно закешировать значения перечислений и пр. А если вставить структуру в фиксированную структуру, то её даже менять можно ;)
Shmell; bulpi; +2 Ответить
6. CyberCerber 852 13.01.21 21:58 Сейчас в теме
(1) Да, но все равно это могут быть только те значения, которые могут мигрировать между клиентом и сервером
9. markers 274 14.01.21 01:55 Сейчас в теме
(6) Это само-собой! Но данная возможность как по мне, недооценена и некоторые не знают о ней.
10. markers 274 14.01.21 05:01 Сейчас в теме
(6) + Имея такую фиксированную структуру / фиксированный массив в реквизите формы, можно имитировать ту же таблицу значений, которой нет на клиенте и многое другие можно передавать в более простых типах.
12. SlavaKron 14.01.21 08:56 Сейчас в теме
(10) Можно поподробнее, в чем преимущество именно фиксированной коллекции перед обычной в контексте обсуждения?
13. markers 274 14.01.21 09:12 Сейчас в теме
(12) Тут речь идет не о преимуществе или недостатке фиксированной коллекции над стандартной, а том что если есть задача использовать массив/структуру/соответствие при обмене данными между клиентом и сервером (некие общие данные, а не передаваемые параметрами) , то использовать переменные нельзя (в этой статье описано почему), создать реквизит формы такого типа нельзя, но можно создать реквизит формы произвольного типа и сохранять в него фиксированную коллекцию, другую платформа просто не примет.
14. SlavaKron 14.01.21 09:19 Сейчас в теме
(13)
другую платформа просто не примет

У меня почему-то принимает. Реквизит1 - реквизит формы типа произвольный. При открытии всё отрабатывается без ошибок.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Реквизит1 = Новый Структура;
	Реквизит1.Вставить("Сообщение", "Привет!");
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	Сообщить(Реквизит1.Сообщение);
КонецПроцедуры
Показать
15. markers 274 14.01.21 09:21 Сейчас в теме
(14) Какая платформа у вас? Может что изменилось со времен 8.3.11 в лучшую сторону. Попробуйте на клиенте его ещё изменить
16. SlavaKron 14.01.21 09:26 Сейчас в теме
(15) 8.3.16 в режиме совместимости 8.3.12. Изменения на клиенте видны на сервере. Проверил так:
&НаКлиенте
Процедура Команда1(Команда)
	Реквизит1.Сообщение = "Пока!";
	Команда1НаСервере();
КонецПроцедуры

&НаСервере
Процедура Команда1НаСервере()
	Сообщить(Реквизит1.Сообщение);
КонецПроцедуры
Показать

Только это было и до 8.3.12. Еще в 8.3.10 в конфигурациях от БИТов использовали произвольный реквизит, которому присваивали обычную структуру для хранения кэша формы.
17. markers 274 14.01.21 09:31 Сейчас в теме
(16) Не внимательно прочитал код выше. Извините.
19. SlavaKron 14.01.21 09:32 Сейчас в теме
(17) В приведенном коде реквизит и меняется на клиенте.
18. CyberCerber 852 14.01.21 09:32 Сейчас в теме
(15) На сколько я помню, структуру и массив можно было всегда использовать в произвольном реквизите.
Может, вы путаете с параметрами сеанса, там есть подобное ограничение.
FatPanzer; +1 Ответить
20. markers 274 14.01.21 09:34 Сейчас в теме
(18) Нет-нет. Будем считать что я что-то перепутал, но я прям помню ошибку, что можно использовать только фиксированные коллекции. Это даже повод мне позже перепроверить и за счет этого немного упросить код в некоторых местах.
21. markers 274 14.01.21 09:57 Сейчас в теме
(20) Проверил, истина как всегда - где-то между:
1) Использовать структуру - можно
2) Использовать соответствие - нельзя, фиксированную - можно
тык
3) Использовать массив - нельзя, фиксированный - можно
тык
Хорошо что эта тема поднялась, теперь я знаю что структуру можно использовать без проблем, это очень хорошо.
Тестировалось на 8.3.11.3133 в режиме совместимости с 8.3.10
PS: Почему-то картинки не подтянулись, продублировал ссылкой
cefew; bulpi; RustIG; user1503726; CyberCerber; +5 Ответить
22. markers 274 14.01.21 10:19 Сейчас в теме
(21) Мдя, решил дальше изучить вопрос и как мне казалось, что в такую структуру нельзя будет засунуть соответствие, но простой тест:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	ТестРеквизит = Новый Структура("Тест, тест2", Новый Соответствие, Новый Массив);
	ТестРеквизит.Тест.Вставить("а", "б");
	ТестРеквизит.тест2.Добавить("г");
	
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	Сообщить(ТестРеквизит.Тест.Получить("а")); // Выводит "б"
	Сообщить(ТестРеквизит.тест2[0]); // Выводит "г"
	
	ТестРеквизит.Тест.Вставить("а", "в");
	ТестРеквизит.Тест.Вставить("б", "а");
	
	ТестРеквизит.тест2.Добавить("д");
	
КонецПроцедуры
Показать

Показал, что всё-равно что лежит в структуре. Не понятен тогда смысл ограничений в хранении сразу не фиксированного значения соответствия/массива.
CyberCerber; +1 Ответить
23. CyberCerber 852 14.01.21 10:22 Сейчас в теме
(22) Хе-хе, да, т.е. тупо проверяется только тип самого реквизита. А так-то массив и соответсвие могут обмениваться между клиентом и сервером. Похоже на какую-то быструю заглушку.
24. markers 274 14.01.21 10:28 Сейчас в теме
(23) Больше похоже не на заглушку, а наличие некоего "белого" списка допустимых типов и в него просто забыли включить Соответствие и Массив, так как они по сравнению с структурой сильно меньше используется (ну массив ещё под вопросом конечно)
25. CyberCerber 852 14.01.21 10:33 Сейчас в теме
(24) Да, массив под большим вопросом. :-) Ну, на форме вместо него можно использовать список
2. RustIG 1351 13.01.21 18:16 Сейчас в теме
глубоко разобраны некоторые аспекты, но, пожалуй, держать в голове все нюансы сложно, одна надежда, что платформу будут развивать, и сама платформа будет подсказывать нюансы.
3. FatPanzer 13.01.21 18:38 Сейчас в теме
Помнится я такое делал, да. Когда продукт являлся внешней обработкой, и формы исполняли роль общих модулей...
4. partizand 129 13.01.21 19:53 Сейчас в теме
Очень интересный и необычнвй взгляд!
На мой взгляд разработчики платформы сами себе усложнили жизнь делением на видимость модулей, разорвав контекст. Что приводит иногда к сложностям.
И простите, но сравнивать UDP с http не корректно. UDP это протокол транспортного уровня, а http прикладного. UDP нужно срвнивать с TCP.
Ваши обмены могут так же использовать и TCP протокол (при условии доступов). Очень дико это читать.
И фраза "за секунду точно должны получить ответ" вызывает недоумение.
Как и "Довольно простой протокол, но не очень широко известен". Не стоит так писать 😃
charmillion; logos; slauter77; user1513128; Shmell; ubnkfl; VrYasuyk; ltfriend; pavlov_dv; +9 Ответить
7. CyberCerber 852 13.01.21 22:00 Сейчас в теме
(4) Да, возможно рассказал про все эти протоколы слишком дилетански, на пальцах. Может, соберусь и что-то в тексте подправлю.
33. ubnkfl 14.01.21 17:23 Сейчас в теме
(7) вы просто спутали один с другим. TCP и HTTP.
35. CyberCerber 852 14.01.21 17:25 Сейчас в теме
(33) Да, я рассказал про HTTP на основе TCP. Уже поправил в статье.
11. ltfriend 954 14.01.21 08:17 Сейчас в теме
(4) По поводу протоколов хотел примерно тоже самое написать, но вы меня опередили )
Как и "Довольно простой протокол, но не очень широко известен".

Если добавить фразу "среди программистов 1С", то можно согласиться )
charmillion; +1 Ответить
31. Xershi 1474 14.01.21 17:13 Сейчас в теме
(11) забыли добавить "программистов". Программист это все знает.
5. qazaz2 16 13.01.21 20:39 Сейчас в теме
Вот так живешь, работаешь, думаешь что понимаешь что-то про 1С. И тут на тебе.
Ну нельзя же так!
Хоть бы предупреждение какое-то сделали, "минздрав не рекомендует, возможно обрушение ЧСВ".
8. CyberCerber 852 13.01.21 22:01 Сейчас в теме
(5) Рад, что статья произвела на вас впечатление. :-)
26. Vortigaunt 96 14.01.21 14:41 Сейчас в теме
Спасибо за статью. Тоже несколько раз пытался использовать Обработки как универсальные объекты в терминах ООП со свойствами и методами. Привлекала именно поддержка контекстной подсказки, чтобы упростить поддержку какого-нибудь хитрого обмена на http-сервисах, пакетах xdto и всем таком.

Но постоянно сталкивался, что реквизиту нельзя присвоить ссылку на объект обработки. А значит я не могу созданные объекты обработки хранить в реквизитах других обработок. Помещать в коллекции: массив, таблицазначений, структура.
В статье это тоже не освещено. Есть идеи?
27. CyberCerber 852 14.01.21 14:46 Сейчас в теме
(26) Не совсем понял, вы про обработки или формы? Если про обработки, то для реквизита обработки можно выбрать тип ОбработкаОбъект, я сам так делал, когда как раз использовал принципы ООП.
28. Vortigaunt 96 14.01.21 15:04 Сейчас в теме
(27) Извините. Уже подзабыл в чем была проблема. Действительно для реквизита обработки можно указать тип ОбработкаОбъект. Для реквизита табличной части обработки нельзя указать тип ОбработкаОбъект. А я хотел обработками продублировать структуру XDTO пакета для обменов.
29. CyberCerber 852 14.01.21 15:21 Сейчас в теме
(28) Да, действительно, нельзя. Ну, таких задач у меня еще не было.
Сейчас ничего красивого не придумывается. Разве что только ХранилищеЗначения или ЗначениеВСтрокуВнутр
30. partizand 129 14.01.21 16:30 Сейчас в теме
А еще подскажите, зачем именно на клиенте работать с Udp? Зачем это в каждой форме нужно делать?

Что там со стороны ДО, там же висит сетевой сервер ожидая подключения на порту, он на клиенте висит же? Это какая-то скрытая форма стартует или в каждой форме по серверу? Не ясна реализация сервера. Ну и не очень хорошо на клиенте висеть с открытым портом.

И можно сделать немного по другому, через веб сервис:
Повесить на ДО например веб сервис (если это вообще не через odata можно сделать), который принимает на вход параметры бизнес-процесса и создает БП у пользователя. А форму заполнения БП сделать в УТ. Тогда и базу не нужно открывать. Судя по картинке нужно знать только список исполнителей.
Хотя задачу не знаю, может такой вариант не подойдет. Но меня всегда тянет к стандартным механизмам и реализациям...

В общем ваша реализация вызывает у меня сомнения, простите :)
32. CyberCerber 852 14.01.21 17:21 Сейчас в теме
(30) Нет, здесь сервер не подойдет, вы, наверное, не совсем поняли задачу...
У пользователя открыто на клиентском компе две базы. Он нажимает кнопку в одной, ему открывается форма создания нового бизнес-процесса в другой. Т.е. идет общение именно на клиентском уровне, без сервера.
То, что вы рассказали - это похоже на бесшовную интеграцию Документооборота с другими конфигурациями. Тоже хороший механизм, но несколько другое.
Но а в каждой конфигурации есть только одна специальная скрытая форма, которая слушает порт.
34. Darklight 32 14.01.21 17:24 Сейчас в теме
Давно уже вынашиваю эту идею, но статью пока не было времени написать. Спасибо за подробное изложение
36. ixijixi 1775 14.01.21 22:34 Сейчас в теме
Использовал прием КонтейнерКлиентскихМетодов в одной из своих разработок, когда во внешей обработке куча взаимодействующих между собой форм и не хотелось дублировать одинаковые методы из формы в форму. Завел пустую форму и вынес все общие обработчики туда. Работает, и кстати даже без тормозов.

P.S. Шутка про UDP была уже?
37. CyberCerber 852 14.01.21 22:36 Сейчас в теме
(36) Наверное, была но не дошла. :-)
38. dabu-dabu 289 15.01.21 16:49 Сейчас в теме
Хорошая статья, но не хватает оценки скорости работы через форму в сравнении с общим модулем
39. triviumfan 92 15.01.21 17:02 Сейчас в теме
Такое уже давно практикуется, только зачем - мне не понятно.
40. boln 1040 15.01.21 22:04 Сейчас в теме
Давненько использую форму как абстрактный класс - предок для создания своих простеньких классов. Например, класс Стек.
Прикрепленные файлы:
41. CyberCerber 852 15.01.21 22:07 Сейчас в теме
(40) Классно, было бы интересно почитать подробнее
42. boln 1040 15.01.21 22:12 Сейчас в теме
(41) Ох, долго расписывать... Это было придумано для асинхронного кода "через коллбэк", для синхронизации вызова вложенных процедур, еще до 8.3.18, когда появилось Ждать ...Асинх().

Ну, курс УЦ-3 по АП вряд ли заинтересует, но вдруг:
https://www.1c-uc3.ru/asinhron.html
43. Jimbo 9 21.01.21 15:56 Сейчас в теме
Диверсия с подменами партнера и цен удалась ?
Служба безопасности ж найдёт по журналу регистрации автора )
44. Yashazz 4709 23.08.21 09:48 Сейчас в теме
Нового абсолютно ничего, формы как псевдо-объекты или псевдо-модули используются ещё с 7.7, но расписано достаточно подробно и объём усилий, затраченных на публикацию, достоин уважения. А вот незнание автора, что можно и что нельзя пихать в реквизиты либо параметры формы - уважения явно не заслуживает. Берясь за подобную тему, следует уделять внимание таким важным вопросам.
А вот зачем было в одном рассказе смешивать протокол обмена и формы, не уразумел.
45. CyberCerber 852 23.08.21 10:29 Сейчас в теме
(44) Подскажите, а где у меня ошибка по типам в переменных и реквизитах?
46. Yashazz 4709 23.08.21 10:32 Сейчас в теме
(45) Утверждения (6) и (18) как минимум.
Оставьте свое сообщение