Как ограничить доступ, чтобы программисту ночью спать спокойно

18.07.23

Разработка - Инструментарий разработчика

Размышления на тему стандартизации алгоритмов формирования отчетов при работе в двух базах.

Скачать исходный код

Наименование Файл Версия Размер
Обработка подключения
.epf 9,51Kb
1
.epf 9,51Kb 1 Скачать
Расширение предоставления доступа
.cfe 29,32Kb
0
.cfe 29,32Kb Скачать

Как ограничить доступ к базе, но разрешить печатать отчеты?

Как отладить отчеты там, где они исполняются?

Как перестать страдать из-за разных версий одного отчета?

Как сделать так, чтобы пользователи работали в одной базе?

 

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

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

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

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

Вариант №1.

Можно поставить ему набор прав «бухгалтер» (или аналогичное) и порезать интерфейс. Все хорошо, отчеты печатаются, все довольны. Но есть нюансы:

  1. Если оператор умен, он сможет открыть все, что доступно бухгалтеру, и сделать свое черное дело;
  2. Он вынужден сидеть в двух базах. В одной для работы, а в другой для отчетов.

Внешняя обработка с макетом и формой с параметрами и кнопкой сформировать:

&НаКлиенте
Процедура Сформировать(Команда)
    ВывестиТабличныйДокумент();          
КонецПроцедуры

&НаСервере
Процедура ВывестиТабличныйДокумент()
     ТабДокумент.Очистить();        
     ПараметрыОтчета = Новый Структура;
     ПараметрыОтчета.Вставить("НачалоПериода", Отчет.НачалоПериода);
     ПараметрыОтчета.Вставить("КонецПериода", КонецДня(Отчет.КонецПериода));
     ПараметрыОтчета.Вставить("Организация", Отчет.Организация);
     ПараметрыОтчета.Вставить("ВидРМ", Отчет.ВидРМ);
     ПараметрыОтчета.Вставить("ПоказыватьТовары", ПоказыватьТовары);
     ТабДокумент.Вывести(СформироватьТабличныйДокумент(ПараметрыОтчета));
     ТабДокумент.ФиксацияСлева = 4;
КонецПроцедуры

&НаСервере
Функция СформироватьТабличныйДокумент(ПараметрыОтчета)
     ТабДок = Новый ТабличныйДокумент;
     // какой-то запрос
     //какой-то алгоритм заполнения ТабДок
     Возврат ТабДок;           
КонецФункции

 

Вариант №2.

Давайте назначим ему права «только чтение»! Ну и порежем интерфейс… Проблемы те же (ну разве что базу не поломает кривыми руками). И добавляется еще невозможность печати и сохранения отчетов.

Код пока не меняется

Вариант №3.

Давайте перепишем права! Если политика позволяет так сделать, то все хорошо. Дописываем права в старшей программе, и пользователь не влезет, и, даже не увидит, что там есть лишнего. Но он при этом продолжает работать в двух базах, а еще у нас теперь переписана старшая база и программист перед очередным обновлением говорит нам за это "спасибо."

Вариант №4.

А что если вообще не пускать пользователя в бухгалтерию и вытаскивать данные из старшей программы по com соединению?

Хороший вариант. Чтобы его реализовать, необходимо перенести из старшей программы код отчетов, переписать все запросы и убедиться, что туда-сюда в составе данных «летают» не ссылки, а примитивные типы. Теперь операторы довольны окончательно! Ведь работают они в одной базе.

Однако программист, обновляющий старшую базу, начинает получать странные сообщения от пользователей других баз: «Вы там что-то вчера делали ночью на сервере, а у нас отчеты не работают!». Странные они, потому что обновляет он одну базу, а ошибки начинаются в другой. Но эти сообщения перестают быть странными, как только программист вспоминает, что полгода назад что-то такое он делал с отчетами в других базах. Но отладить теперь эти отчеты становится трудно, так как все, «что было в Вегасе, остается в Вегасе». А на стороне отладки просто ошибка где-то с чем-то.

Вариант №5.

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

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

Формируется набор заповедей:

Не создай пользователю второй базы!

Храни запросы и алгоритмы на стороне старшей базы!

Не нажми кнопку "включить возможность изменения"!

Не дублируй код!

Не передай данных без проверок!

Не оставь пользователя без подробностей ошибки!

Чек лист, или порядок действий:

  1. Создаем расширение на стороне старшей программы.
  2. Закидываем в нее необходимые внешние отчеты и обработки (не забываем менять «отчет.» на «объект.»;
  3. Создаем общий модуль «сервер» и «внешнее соединение», через который будем «держать связь»;
  4. Предусматриваем всевозможные ошибки и делаем какую-никакую обратную связь (см. ниже про ошибки);
  5. На стороне остальных программ организуем универсальное подключение с передачей всех параметров и «встречу» готовых печатных форм.

С учетом того, что «клиентом» каждого отчета у нас теперь являются 2 базы, необходимо устранить разночтения. Для этого исходные параметры отчета, полученные в виде кодов, наименований и других идентификаторов справочников и документов, в отдельной процедуре в единой функции (например, «ПреобразоватьПараметрыОтчета(ВходящиеПараметры)») нужно преобразовать перед выполнением алгоритма в обычные ссылочные типы и передать в типовую процедуру на стороне старшей программы. Так отладку будет легче делать. И все алгоритмы будут в одном месте.

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

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

Теперь перейдем к сторонней программе. Мы договорились, что будем заполнять параметры примитивными типами, что, по-хорошему, необходимо реализовать исходя из настроек синхронизации. Ну, или как проще, если мы в Time-to-market и «итеративная поставка».

Так же необходимо реализовать само подключение. Если есть отдельный пользователь для удаленного подключения к старшей базе, то лучше жестко прописать его данные и вообще не показывать пользователю, затем организовать подключение на стороне сервера и #std642. Если авторизация средствами ОС и база на сервере, то подключение на стороне клиента и #std755.

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

В модуле формы отчета строка:

ТабДокумент.Вывести(СформироватьТабличныйДокумент(ПараметрыОтчета));

Меняется на:

ТабДокумент.Вывести(ДВП_МодульВнешнегоСоединения.СформироватьТабличныйДокумент(ПараметрыОтчета));

Функция СформироватьТабличныйДокумент, как видно, переносится в общий модуль.

Там же создаем функцию СформироватьТабличныйДокументИзВнешнейБазы

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

Она преобразует параметры из примитивных типов и продолжает наш старый алгоритм, если все хорошо.

Код функции преобразования:

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

    Если не ВнешниеПараметрыОтчета.Свойство("ОрганизацияКПП") Тогда
        ТекстОшибки = ТекстОшибки + Символы.ПС +
        "КПП организации не указано!";
        Отказ = Истина;
    КонецЕсли;

    Если не ВнешниеПараметрыОтчета.Свойство("ВидРМ") Тогда
        ТекстОшибки = ТекстОшибки + Символы.ПС +
        "Вид номенклатуры не указано!";
        Отказ = Истина;
    КонецЕсли;
    Если не ВнешниеПараметрыОтчета.Свойство("ПоказыватьТовары") Тогда
        ТекстОшибки = ТекстОшибки + Символы.ПС +
        "Значение флага *показывать товары* не указано!";
        Отказ = Истина;
    КонецЕсли;
       
    ПараметрыОтчета = Новый Структура;
    Если Отказ Тогда
        ПараметрыОтчета.Вставить("Ошибка", ТекстОшибки);
        Возврат ПараметрыОтчета;
    КонецЕсли;

    Организация = ОпределитьОрганизацию(ВнешниеПараметрыОтчета.ОрганизацияИНН, ВнешниеПараметрыОтчета.ОрганизацияКПП);
    Если Организация = Неопределено тогда
        ТекстОшибки = ТекстОшибки + Символы.ПС +
        "Организация не найдена!";
        Отказ = Истина;
     КонецЕсли;
     ВидРМ = Справочники.ВидыНоменклатуры.НайтиПоНаименованию(ВнешниеПараметрыОтчета.ВидРМ);
     Если не ЗначениеЗаполнено(ВидРМ) тогда
        ТекстОшибки = ТекстОшибки + Символы.ПС +
        "Вид номенклатуры не найден!";
        Отказ = Истина;
     КонецЕсли;
       
     Если Отказ Тогда
        ПараметрыОтчета.Вставить("Ошибка", ТекстОшибки);
        Возврат ПараметрыОтчета;
     КонецЕсли;
       
     ПараметрыОтчета.Вставить("НачалоПериода", ВнешниеПараметрыОтчета.НачалоПериода);
     ПараметрыОтчета.Вставить("КонецПериода", КонецДня(ВнешниеПараметрыОтчета.КонецПериода));
     ПараметрыОтчета.Вставить("Организация", Организация);
     ПараметрыОтчета.Вставить("ВидРМ", ВидРМ);
     ПараметрыОтчета.Вставить("ПоказыватьТовары", ВнешниеПараметрыОтчета.ПоказыватьТовары);
     Возврат ПараметрыОтчета;
КонецФункции

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

Код:

Функция СформироватьПустойТабличныйДокумент(ТекстСообщения) ЭКСПОРТ
    ТабДок = Новый ТабличныйДокумент;
    Макет  = ПолучитьОбщийМакет("ДВП_МакетСообщение");
    ОбластьШапки = Макет.ПолучитьОбласть("Сообщение");
    ОбластьШапки.Параметры.ТекстСообщения = ТекстСообщения;
    ТабДок.Вывести(ОбластьШапки);
    Возврат ТабДок;
КонецФункции

 

Важное дополнение! Мы договорились, что обратно будут передаваться готовые печатные формы, но они не передаются! Есть команда ЗначениеВСтрокуВнутр. Тогда в базу пользователя «полетит» текст.

Теперь посмотрим, какой код на стороне сторонней базы с оператором на той стороне монитора.

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

&НаСервере
Функция ПолучитьПараметрыОтчета()
    ПараметрыОтчета = Новый Структура;
    ПараметрыОтчета.Вставить("НачалоПериода", Объект.НачалоПериода);
    ПараметрыОтчета.Вставить("КонецПериода", КонецДня(Объект.КонецПериода));
    ПараметрыОтчета.Вставить("ОрганизацияИНН", Объект.Организация.ИНН);
    ПараметрыОтчета.Вставить("ОрганизацияКПП" , Объект.Организация.КПП);
    ПараметрыОтчета.Вставить("ВидРМ", Объект.ВидРМ.Наименование);
    ПараметрыОтчета.Вставить("ПоказыватьТовары", ПоказыватьТовары);
    ПараметрыОтчета.Вставить("ЭтоВнешняяБаза", Истина);
       
    Возврат ПараметрыОтчета;
КонецФункции

Затем, в процедуре формирующей отчет (ВывестиТабличныйДокумент()) заменить строку, отвечающую за вызов функции формирования табличного документа на:

ТабДокумент.Вывести(ЗначениеИзСтрокиВнутр(Подключение.ДВП_МодульВнешнегоСоединения.СформироватьТабличныйДокументИзВнешнейБазы(ПараметрыОтчета)));

Видим, что добавилась переменная «Подключение». Она и будет содержать настройки подключения и выполнять его:

   СтрокаПодключения = ПолучитьСтрокуПодключения();
   КомКоннектор = Новый COMОбъект("V83.ComConnector.1");
   Попытка
       БазаБП = КомКоннектор.Connect(СтрокаПодключения);
       Возврат БазаБП;
   Исключение
       ОбщегоНазначения.СообщитьПользователю(ОписаниеОшибки());
   КонецПопытки;
   Возврат неопределено;

 

СтрокаПодключения это переменная, содержащая параметры подключения. Там все банально. Помним только, что если авторизация средствами ОС, то передавать в ней имя пользователя и пароль не надо.

Кстати, если подключение выполняется на стороне сервера, то пользователем будет sa, userV8 или под кем там запущен сервер 1С. Если надо доменного пользователя, тогда подключение необходимо делать на стороне клиента:

 

&НаКлиенте
Функция ПодключитьсяКБазеБухгалтерии()
       
   СтрокаПодключения = ПолучитьСтрокуПодключения();
   КомКоннектор = Новый COMОбъект("V83.ComConnector.1");
   Попытка
       БазаБП = КомКоннектор.Connect(СтрокаПодключения);
       Возврат БазаБП;
   Исключение
       ОбщегоНазначенияКлиент.СообщитьПользователю(ОписаниеОшибки());
   КонецПопытки;
   Возврат Неопределено;
КонецФункции

В качестве бонуса, пример отчета, вытаскивающего данные о продажах через розничные точки с разбивкой на наше/не наше.

Расширение тестировалось на 1С:Бухгалтерия 3.0.128.35. обработка на любой базе с БСП на платформе 8.3.21.1644.

Доступ COM-соединение авторизация ОС стандартизация качество кода

См. также

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

10000 руб.

02.09.2020    127276    689    389    

740

SALE! 10%

Перенос данных из УПП 1.3 в ERP 2 / УТ 11 / КА 2. Переносятся документы, справочная информация и остатки

Перенос данных 1C Платформа 1С v8.3 1С:Управление производственным предприятием 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

Перенос документов, начальных остатков и справочной информации из УПП 1.3 в ERP 2 | из УПП 1.3 в УТ 11 | из УПП в КА 2 | Правила конвертации (КД 2) в продаже с 2015 года, постоянно работаем над их развитием | Более 360 предприятий выполнили переход с использованием этого продукта! | Сэкономьте время - используйте готовое решение для перехода! | Позволяет перенести из УПП 1.3 в ERP / УТ 11 / КА 2 всю возможную информацию | В переносе есть фильтр по организации и множество других опциональных параметров выгрузки | Есть несколько алгоритмов выгрузки остатков на выбор

50722 45650 руб.

04.08.2015    160702    357    268    

349

SALE! 10%

[ED3] Обмен для ERP 2.5, КА 2.5, УТ 11.5 БП 3.0, Розница, УНФ и других с EnterpriseData (универсальный формат обмена), правила обмена

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Россия Платные (руб)

Правила в универсальном формате обмена для ERP 2.5, КА 2.5, УТ 11.5, БП 3.0, Розница, УНФ, для последних версий конфигураций. Ссылки на другие конфигурации в описании публикации. Правила совместимы со всеми другими версиями конфигураций новыми и старыми, поддерживающими обмен в формате EnterpriseData. Не требуется синхронного обновления правил после обновления другой конфигурации, участвующей в обмене. Типовой обмен через планы обмена кнопкой Синхронизация вручную или автоматически по расписанию, или вручную обработкой.

25080 руб.

12.06.2017    135905    732    291    

393

SALE! 10%

Перенос данных из ERP 2 / КА 2 / УТ 11 в БП 3.0. Переносятся документы, начальные остатки и справочники

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

Перенос данных из ERP в БП 3 | из КА 2 в БП 3 | из УТ 11 в БП 3 | из ЕРП в БП 3 | В продаже с 2019г. | Воспользовались более 176 предприятий! | Сэкономьте время - используйте готовое решение для перехода! | Перенос разработан в формате КД 2 (правила конвертации данных) | Переносятся все возможные виды документов, начальных остатков и нормативно-справочная информация| Можно опционально выгружать каждую пару "номенклатура+характеристика" как отдельную номенклатуру | Есть выгрузка настроек счетов учета и зарплатных данных из ERP / КА 2 | Можно проверить на вашем сервере перед покупкой, обращайтесь!

38500 34650 руб.

15.04.2019    69081    181    139    

111

SALE! 10%

Перенос данных из БП 3.0 в УТ 11 / КА 2 / ERP 2. Переносятся начальные остатки, документы и справочники

Перенос данных 1C Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

В продаже с 2014г. | Воспользовались более 122 предприятий! | Перенос данных из БП 3.0 в УТ 11 | из БП 3.0 в КА 2 | из БП 3.0 в ERP | Сэкономьте свое время - используйте готовое решение для перехода! | Постоянно работаем над развитием переноса данных | Обновляем на новые релизы 1С | Есть фильтр выгрузки по организациям | Переносятся начальные остатки на выбранную дату, документы за период времени и вся возможная справочная информация | Перенос сделан на технологии КД 2 (правила конвертации данных)

50722 45650 руб.

31.10.2014    232473    126    327    

298

Перенос данных из УПП 1.3 в БП 3.0. Переносятся документы (обороты за период), справочная информация и остатки

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 1С:Управление производственным предприятием 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Управленческий учет Платные (руб)

Перенос данных из 1С:Управление производственным предприятием 1.3 в 1С:Бухгалтерия предприятия 3.0 с помощью правил обмена. Переносятся остатки, документы (обороты за период), справочная информация. Правила проверены на конфигурациях УПП 1.3 (1.3.226.x) и БП 3.0 (3.0.151.x). Правила подходят для версии ПРОФ и КОРП.

28000 руб.

15.12.2021    20740    136    38    

95

Перенос данных из УТ 10.3 в УТ 11.5. Переносятся документы (обороты за период), справочная информация и остатки

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 Оперативный учет 1С:Управление торговлей 10 1С:Управление торговлей 11 Россия Управленческий учет Платные (руб)

Перенос данных из 1С:Управление торговлей 10.3 в 1С:Управление торговлей 11.5 с помощью правил обмена. Переносятся остатки, документы (обороты за период), справочная информация. Правила проверены на конфигурациях УТ 10.3 (10.3.87.x) и УТ 11.5 (11.5.16.x).

28000 руб.

23.07.2020    46968    201    64    

162

SALE! 10%

Перенос данных из ERP 2 / КА 2 в ЗУП 3. Переносятся остатки, документы и справочники

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Россия Бухгалтерский учет Управленческий учет Платные (руб)

Перенос данных из ERP в ЗУП 3 | из КА 2 в ЗУП | Воспользовались более 79 предприятий! | Предлагаем приобрести готовые правила конвертации данных (КД 2) для переноса остатков, документов с движениями и справочной информации 3 | В продаже с 2020г. | Оперативно обновляем правила до актуальных релизов 1С | Есть перенос начальной задолженности по зарплате и начальной штатной расстановки на выбранную дату | Обороты за прошлые годы (данные для расчета среднего) переносятся свернуто в документ "Перенос данных" | Есть фильтр по организациям | Документы за текущий период переносятся сразу с движениями, поэтому не потребуется делать перерасчеты | Перенос можно проверить перед покупкой, обращайтесь!

48278 43450 руб.

03.12.2020    34568    83    58    

81
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. sandr13 34 19.07.23 12:17 Сейчас в теме
А через веб-сервис это не получится сделать?
2. s03 20.07.23 06:52 Сейчас в теме
(1) легко, да и будет намного проще, если на сервере используется несколько разных платформ (вспоминаем грабли с COM в этих случаях)
Да и ЗначениеВСтрокуВнутр давно считается устаревшей и 1С не будет гарантировать её наличие в дальнейшем, поэтому я бы поместил результат в ХранилищеЗначения, а его перевёл бы в двойные данные и уже в таком виде и возвращал бы как ответ на http-запрос (обратное преобразование тоже не составляет никаких сложностей)
3. Keath 24 21.07.23 12:04 Сейчас в теме
(2)Согласен. Это будет уже следующий, 6 шаг эволюции.
Оставьте свое сообщение