Библиотека A1s: облегчение повседневной разработки в 1С

20.05.25

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

Представление A1s — компактной и легко читаемой библиотеки для повседневной разработки в 1С.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование Бесплатно
Библиотека A1s: облегчение повседневной разработки в 1С:
.cf 112,85Kb
22
22 Скачать бесплатно

 

Библиотека A1s: облегчение повседневной разработки в 1С

1. Введение

Библиотека A1s — это утилитарный набор модулей для разработки на платформе 1С:Предприятие с поддержкой как серверного, так и клиентского исполнения. Она создана для того, чтобы упростить и сократить код в типовых задачах: запросы, логирование, сериализация, работа со строками.

A1s не зависит от БСП, может быть включена в состав конфигурации как в виде отдельных общих модулей, так и целиком как набор модулей. Допускает использование как на сервере, так и на клиенте (для модулей A1sS, A1sChars, A1sJ, A1sX).

Библиотека подходит как для внутренних проектов, так и для open source-решений, где важна читаемость и чистота кода.


Что позволяет достичь использование A1s

  • Сократить количество кода в типовых сценариях (запросы, логирование, сериализация)

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

  • Упростить поддержку и ревью — в том числе за счёт тестов и doc-комментариев

  • Быстро выполнять локальную или CI-проверку стабильности после изменений

  • Повысить переиспользуемость логики без привязки к БСП

 


2. Состав библиотеки

Модуль

Назначение

A1sQ

Упрощённая работа с запросами (QT + Unload)

A1sS

Строковые утилиты (AsString, Split, Print)

A1sLog

Централизованное логирование (Info, Error, Warn)

A1sJ

JSON-сериализация (ToJSON, FromJSON)

A1sX

XML-сериализация (ToXML, FromXML)

A1sChars

Проверки символов, поиск по алфавиту, утилиты по строкам

 

Модули работы с метаданными (A1sMC, A1sMD, A1sME) — в разработке и будут добавлены в следующих версиях.

 


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

A. Запрос без ручного создания объекта и параметров

QT = "ВЫБРАТЬ Номенклатура ИЗ Справочник.Номенклатура ГДЕ ПометкаУдаления = &Флаг";
data = A1sQ.Unload(QT, Ложь);

B. Логирование события

A1sLog.Warn("Превышен лимит", Комментарий);

C. JSON-сериализация

строка = A1sJ.ToJSON(Структура);

D. Работа со строками

A1sS.Print("Документ записан: " + Ссылка);

Оптимизация реального кода из типовой

В конфигурации 1С:Бухгалтерия выбираю первый попавшийся запрос.
Он вытаскивает задачи исполнителей, связанные с бизнес-процессом. И прошу ИИ-помощника по библиотеке переписать код с использованием A1s и ее стандартов кода.
 

🚫 До (типовой 1С-код)

Запрос = Новый Запрос( "ВЫБРАТЬ
   | Задачи.Ссылка КАК Ссылка
   |ИЗ
   | Задача.ЗадачаИсполнителя КАК Задачи
   |ГДЕ
   | Задачи.БизнесПроцесс = &БизнесПроцесс");

Запрос.УстановитьПараметр("БизнесПроцесс", Ссылка);
ВыборкаДетальныеЗаписи = Запрос.Выполнить().Выбрать();

 

Минусы:

  • Повторяемый шаблон: Новый Запрос, УстановитьПараметр, Выполнить().Выбрать()

  • Нет обработки ошибок

  • Нет форматирования или повторного использования


После (с использованием A1s)

&НаСервере
Function GetДеталиПоБизнесПроцессу(ссылка) Export

   ib = "ЗАГРУЗКА ДЕТАЛЬНЫХ ЗАДАЧ ПО ССЫЛКЕ НА БИЗНЕС-ПРОЦЕСС";
  Try
      // ТЕКСТ ЗАПРОСА
      QT = "ВЫБРАТЬ
      | Задачи.Ссылка КАК Ссылка
      |ИЗ
      | Задача.ЗадачаИсполнителя КАК Задачи
      |ГДЕ
      | Задачи.БизнесПроцесс = &БизнесПроцесс"; 


      // ВЫПОЛНЕНИЕ ЗАПРОСА С ПАРАМЕТРОМ
      таблица = A1sQ.Unload(QT, ссылка);
      // ВОЗВРАТ РЕЗУЛЬТАТА
      Return таблица;
   Except
      A1sS.Print(ib + ": ошибка выполнения запроса - " + ErrorDescription()); 
      Return Новый ТаблицаЗначений;
   EndTry;
EndFunction

 

Преимущества:

  • Используется QT + A1sQ.Unload — лаконично и понятно

  • Добавлена Try...Except-обработка ошибок

  • Комментарии-интенции (ib = "...") позволяют централизованно выводить контекст

  • Именование и стиль по стандарту библиотеки A1s

  • Код создается ИИ-помощником 👉 https://chatgpt.com/g/g-680318fd045c8191b8ffef6abb7aea12-a1s-assistent-1s-bystryi-start


Результат

Минимум кода при получении результатов запроса, максимум читаемости.


4. Стиль и структура кода

  • Все публичные процедуры/функции помечаются как Export, а область выполнения определяется флагами модулей
  • PascalCase — для процедур и функций
  • camelCase — для локальных переменных
  • XML-комментарии (/// <summary>…) — для всех экспортных методов
  • ib = "..." — строка-интенция перед логическим блоком
  • // ЗАГЛАВНЫЕ комментарии — для вызовов A1s

 

5. Тестирование

Каждый модуль содержит процедуру SelfTest() Export с базовыми проверками. Это позволяет быстро проверить работоспособность при обновлениях, а также запускать эти проверки автоматически в составе CI-сценариев (например, при обновлении конфигурации или перед публикацией).

 


6. Как подключить

  • скачать файл конфигурации .cf из вложения к публикации
  • Подключить как внешний общий модуль в своей конфигурации
  • Библиотека не требует дополнительных расширений, не зависит от БСП
  • Распространяется по лицензии MIT (свободное использование)

 


7. Заключение

A1s — это компактная, легко читаемая библиотека для повседневной разработки в 1С.
Она не перегружена абстракциями, не требует фреймворков и подходит как для одиночных проектов, так и для командной разработки.

В будущих версиях планируется поддержка работы с метаданными, типами данных и дальнейшее упрощение взаимодействия с объектами языка 1С.

Для ускоренной генерации кода с использованием A1s доступен AI-ассистент:
👉 https://chatgpt.com/g/g-680318fd045c8191b8ffef6abb7aea12-a1s-assistent-1s-bystryi-start

Ассистент помогает писать процедуры, запросы, автотесты и сопровождает A1s-подход в интерактивном режиме.

 

 

Автор A1s: Вадим Щетинкин

 

A1s общий модуль серверная логика логирование JSON XML сериализация Unload QT запросы 1С утилиты 1С SelfTest CodeStyle Export структура кода CI-проверки без БСП внешний модуль автоматизация 1С

См. также

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

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

15500 руб.

02.09.2020    193439    1065    405    

994

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

Инструмент представляет собой обработку для проведения свёртки или обрезки баз данных. Работает на ЛЮБЫХ конфигурациях (УТ, БП, ERP, УНФ, КА и т.д.). Поддерживаются серверные и файловые базы, управляемые и обычные формы. Может выполнять свертку одновременно в несколько потоков. А так же автоматически, без непосредственного участия пользователя. Решение в Реестре отечественного ПО

8400 руб.

20.08.2024    30638    193    104    

182

Пакетная печать Печатные формы Инструментарий разработчика Программист Платформа 1С v8.3 Запросы 1С:Зарплата и кадры бюджетного учреждения 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 Платные (руб)

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

22200 руб.

06.10.2023    22359    58    19    

88

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

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

15000 руб.

10.11.2023    15187    64    33    

83

Инструментарий разработчика Программист Платформа 1С v8.3 Платные (руб)

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

9360 руб.

17.05.2024    32515    107    48    

152

Инструментарий разработчика Программист 8.3.14 Россия Платные (руб)

Расширение для конфигурации “Конвертация данных 3”. Добавляет подсветку синтаксиса, детальную контекстную подсказку, глобальный поиск по коду.

20000 руб.

07.10.2021    19959    8    32    

44

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

Инструмент для генерации OpenApi (Swagger) спецификаций на основании файлов конфигураций 1С. Это консольное и десктопное приложение на языке Rust с полноценным редактором кода, содержащим автозамену и подсвечивание ошибок для быстрого и безошибочного написания документирующего комментария.

18000 руб.

22.11.2024    1218    1    0    

8
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Adeptus 247 22.05.25 15:49 Сейчас в теме
2. user703054_vadja72 2 22.05.25 21:43 Сейчас в теме
(1) если что-то непонятно, то вот примеры использования:

// A1sQ Usage Examples - Demonstrating the query helper library

#Region Example1_BasicQueryCreation
// Basic query creation and execution
Procedure Example1_BasicQueryCreation()
    
    // Simple query creation
    Query = A1sQ.CreateQ("ВЫБРАТЬ * ИЗ Справочник.Номенклатура");
    
    // Query with parameters using BuildQ
    QueryText = "ВЫБРАТЬ Ссылка, Наименование ИЗ Справочник.Номенклатура ГДЕ Наименование = &Name";
    Query = A1sQ.BuildQ(QueryText, "Товар ABC");
    
    // Execute and get selection
    Selection = Query.Выполнить().Выбрать();
    
EndProcedure
#EndRegion

#Region Example2_QuickExecution
// Quick query execution without intermediate Query object
Procedure Example2_QuickExecution()
    
    // Execute query directly and get selection
    Selection = A1sQ.ExecuteQ(
        "ВЫБРАТЬ Ссылка, Наименование, Артикул 
        |ИЗ Справочник.Номенклатура 
        |ГДЕ НЕ ПометкаУдаления 
        |  И Наименование ПОДОБНО &SearchPattern
        |  И Группа = &Group",
        "%металл%",  // Value1 -> &SearchPattern
        GroupRef     // Value2 -> &Group
    );
    
    // Process results
    While Selection.Следующий() Do
        A1sS.Print("Найдена номенклатура: " + Selection.Наименование);
    EndDo;
    
EndProcedure
#EndRegion

#Region Example3_DataUnloading
// Unloading data to ValueTable and arrays
Procedure Example3_DataUnloading()
    
    // Unload to ValueTable
    QueryText = "ВЫБРАТЬ Ссылка, Наименование, Цена 
                |ИЗ Справочник.Номенклатура 
                |ГДЕ Группа = &Group";
    
    ValueTable = A1sQ.Unload(QueryText, GroupRef);
    
    A1sS.Print("Загружено строк: " + ValueTable.Количество());
    
    // Unload single column to array
    NamesArray = A1sQ.UnloadColumn(
        "ВЫБРАТЬ Наименование ИЗ Справочник.Номенклатура ГДЕ НЕ ПометкаУдаления",
        "Наименование"
    );
    
    For Each Name In NamesArray Do
        A1sS.Print("Наименование: " + Name);
    EndDo;
    
EndProcedure
#EndRegion

#Region Example4_EmptyResultChecking
// Checking if query results are empty
Procedure Example4_EmptyResultChecking()
    
    // Check if specific item exists
    If A1sQ.IsNotEmptyResult(
        "ВЫБРАТЬ ПЕРВЫЕ 1 Ссылка 
        |ИЗ Справочник.Номенклатура 
        |ГДЕ Артикул = &Article", 
        "ART-001") Then
        
        A1sS.Print("Товар с артикулом ART-001 найден");
        
    Else
        
        A1sS.Print("Товар с артикулом ART-001 не найден");
        
    EndIf;
    
    // Check if table is empty
    Table = A1sQ.Unload("ВЫБРАТЬ * ИЗ Справочник.Номенклатура ГДЕ ЛОЖЬ");
    If A1sQ.IsEmptyTable(Table) Then
        A1sS.Print("Таблица пуста");
    EndIf;
    
EndProcedure
#EndRegion

#Region Example5_QTQuickText
// Using QT (Quick Text) functions for rapid query building
Procedure Example5_QTQuickText()
    
    // Build query using QT helper
    Fields = "Ссылка, Наименование, ПометкаУдаления";
    FromWhere = "Справочник.Номенклатура";
    Condition = "Группа = &Group И НЕ ПометкаУдаления";
    
    // Build and execute using QT
    Selection = A1sQ.ExecuteByQT(Fields, FromWhere, Condition, GroupRef);
    
    // Or unload directly to table
    Table = A1sQ.UnloadByQT(Fields, FromWhere, Condition, GroupRef);
    
    // Manual QT building
    QueryText = A1sQ.QT(
        "Ссылка, Наименование", 
        "Справочник.Номенклатура", 
        "НЕ ПометкаУдаления"
    );
    // Result: "ВЫБРАТЬ Ссылка, Наименование ИЗ Справочник.Номенклатура ГДЕ НЕ ПометкаУдаления"
    
EndProcedure
#EndRegion

#Region Example6_ParameterHandling
// Advanced parameter handling
Procedure Example6_ParameterHandling()
    
    // Extract parameters from query text
    QueryText = "ВЫБРАТЬ * ИЗ Таблица ГДЕ Поле1 = &Param1 И Поле2 = &Param2";
    ParamsStructure = A1sQ.GetQParams(QueryText);
    // Returns: {Param1: Undefined, Param2: Undefined}
    
    // Parse parameters from keys and values
    Parameters = A1sQ.ParseParams("Name,Group,Price", "Товар1", GroupRef, 100);
    // Returns: {Name: "Товар1", Group: GroupRef, Price: 100}
    
    // Create query and set parameters
    Query = A1sQ.CreateQ(QueryText);
    A1sQ.SetQParams(Query, Parameters);
    
    // Get query parameters info
    ParamsList = A1sQ.GetParams(Query, True); // True = print parameters
    
EndProcedure
#EndRegion

#Region Example7_TempTables
// Working with temporary tables
Procedure Example7_TempTables()
    
    // Get temporary tables manager
    TempManager = A1sQ.GetTemps();
    
    // Create query with temp tables manager
    Query1 = A1sQ.CreateQ(
        "ВЫБРАТЬ Ссылка, Наименование 
        |ПОМЕСТИТЬ ВременнаяТаблица
        |ИЗ Справочник.Номенклатура 
        |ГДЕ НЕ ПометкаУдаления",
        TempManager
    );
    
    Query1.Выполнить();
    
    // Use temporary table in another query
    Query2 = A1sQ.CreateQ(
        "ВЫБРАТЬ * ИЗ ВременнаяТаблица ГДЕ Наименование ПОДОБНО &Pattern",
        TempManager
    );
    
    Query2.УстановитьПараметр("Pattern", "%металл%");
    Selection = Query2.Выполнить().Выбрать();
    
EndProcedure
#EndRegion

#Region Example8_LikeEscaping
// LIKE operator with proper escaping
Procedure Example8_LikeEscaping()
    
    SearchText = "50% скидка [новинка]";
    EscapedText = A1sQ.EscapeLike(SearchText);
    // Escapes special LIKE characters: %, _, [, ], ^, ~
    
    Pattern = A1sQ.LikePattern(SearchText);
    // Wraps with % and escapes: "%50~% скидка ~[новинка~]%"
    
    Selection = A1sQ.ExecuteQ(
        "ВЫБРАТЬ Наименование 
        |ИЗ Справочник.Номенклатура 
        |ГДЕ Наименование ПОДОБНО &Pattern СПЕЦСИМВОЛ &EscapeChar",
        Pattern,
        "~"
    );
    
EndProcedure
#EndRegion

#Region Example9_ComplexQueries
// Building complex queries with UNION
Procedure Example9_ComplexQueries()
    
    Query1Text = A1sQ.QT(
        "Ссылка, Наименование, ""Номенклатура"" КАК ТипОбъекта",
        "Справочник.Номенклатура",
        "НЕ ПометкаУдаления"
    );
    
    Query2Text = A1sQ.QT(
        "Ссылка, Наименование, ""Услуги"" КАК ТипОбъекта",
        "Справочник.Услуги",
        "НЕ ПометкаУдаления"
    );
    
    // Combine queries with UNION ALL
    CombinedQuery = A1sQ.CombineQT(Query1Text, Query2Text);
    
    // Add separator for readability
    FinalQuery = Query1Text + A1sQ.QuerySeparator() + Query2Text;
    
    // Execute combined query
    AllItems = A1sQ.Unload(CombinedQuery);
    
EndProcedure
#EndRegion

#Region Example10_PracticalUsage
// Practical business scenario
Procedure Example10_PracticalUsage()
    
    // Find overdue invoices with details
    OverdueInvoices = A1sQ.UnloadByQT(
        "Ссылка, Номер, Дата, Контрагент, СуммаДокумента",
        "Документ.СчетНаОплатуПокупателю",
        "Дата < &DateLimit И НЕ Проведен",
        CurrentDate() - 30*24*60*60 // 30 days ago
    );
    
    If Not A1sQ.IsEmptyTable(OverdueInvoices) Then
        
        For Each Invoice In OverdueInvoices Do
            A1sS.Print(StrTemplate(
                "Просроченный счет %1 от %2 на сумму %3",
                Invoice.Номер,
                Format(Invoice.Дата, "ДФ=dd.MM.yyyy"),
                Invoice.СуммаДокумента
            ));
        EndDo;
        
    Else
        
        A1sS.Print("Просроченных счетов не найдено");
        
    EndIf;
    
    // Get first matching record
    FirstInvoice = A1sS.FirstRow(A1sQ.ExecuteQ(
        "ВЫБРАТЬ ПЕРВЫЕ 1 * 
        |ИЗ Документ.СчетНаОплатуПокупателю 
        |ГДЕ Контрагент = &Customer
        |УПОРЯДОЧИТЬ ПО Дата УБЫВ",
        CustomerRef
    ));
    
    If FirstInvoice <> Undefined Then
        A1sS.Print("Последний счет: " + FirstInvoice.Номер);
    EndIf;
    
EndProcedure
#EndRegion
Показать
3. user703054_vadja72 2 22.05.25 21:48 Сейчас в теме
сравнение с типовым кодом:

// A1sQ vs Typical 1C Code - Side by Side Comparison

#Region Example1_SimpleQuery
// ===== TYPICAL 1C CODE =====
Procedure TypicalWay_SimpleQuery()
    
    Query = Новый Запрос;
    Query.Текст = 
    "ВЫБРАТЬ
    |    Номенклатура.Ссылка КАК Ссылка,
    |    Номенклатура.Наименование КАК Наименование
    |ИЗ
    |    Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |    Номенклатура.Группа = &Группа
    |    И НЕ Номенклатура.ПометкаУдаления";
    
    Query.УстановитьПараметр("Группа", ГруппаТоваров);
    
    Результат = Query.Выполнить();
    Выборка = Результат.Выбрать();
    
    Пока Выборка.Следующий() Цикл
        // Process data
        Сообщить(Выборка.Наименование);
    КонецЦикла;
    
КонецПроцедуры

// ===== A1sQ WAY =====
Procedure A1sQWay_SimpleQuery()
    
    // One liner!
    Выборка = A1sQ.ExecuteQ(
        "ВЫБРАТЬ Ссылка, Наименование ИЗ Справочник.Номенклатура ГДЕ Группа = &Группа И НЕ ПометкаУдаления", 
        ГруппаТоваров
    );
    
    Пока Выборка.Следующий() Цикл
        Сообщить(Выборка.Наименование);
    КонецЦикла;
    
КонецПроцедуры
// BENEFIT: 12 lines → 8 lines (33% reduction)
#EndRegion

#Region Example2_ValueTableUnload
// ===== TYPICAL 1C CODE =====
Procedure TypicalWay_UnloadTable()
    
    Query = Новый Запрос;
    Query.Текст = 
    "ВЫБРАТЬ
    |    Номенклатура.Ссылка,
    |    Номенклатура.Наименование,
    |    Номенклатура.Артикул
    |ИЗ
    |    Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |    Номенклатура.Группа = &Группа
    |    И Номенклатура.Наименование ПОДОБНО &Шаблон";
    
    Query.УстановитьПараметр("Группа", ГруппаТоваров);
    Query.УстановитьПараметр("Шаблон", "%" + ПоисковаяСтрока + "%");
    
    Результат = Query.Выполнить();
    ТаблицаЗначений = Результат.Выгрузить();
    
    Если ТаблицаЗначений.Количество() = 0 Тогда
        Сообщить("Данные не найдены");
        Возврат;
    КонецЕсли;
    
КонецПроцедуры

// ===== A1sQ WAY =====
Procedure A1sQWay_UnloadTable()
    
    ТаблицаЗначений = A1sQ.Unload(
        "ВЫБРАТЬ Ссылка, Наименование, Артикул ИЗ Справочник.Номенклатура ГДЕ Группа = &Группа И Наименование ПОДОБНО &Шаблон",
        ГруппаТоваров,
        "%" + ПоисковаяСтрока + "%"
    );
    
    Если A1sQ.IsEmptyTable(ТаблицаЗначений) Тогда
        Сообщить("Данные не найдены");
        Возврат;
    КонецЕсли;
    
КонецПроцедуры
// BENEFIT: 20 lines → 10 lines (50% reduction)
#EndRegion

#Region Example3_ExistenceCheck
// ===== TYPICAL 1C CODE =====
Function TypicalWay_CheckExists(Артикул)
    
    Query = Новый Запрос;
    Query.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |    Номенклатура.Ссылка
    |ИЗ
    |    Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |    Номенклатура.Артикул = &Артикул
    |    И НЕ Номенклатура.ПометкаУдаления";
    
    Query.УстановитьПараметр("Артикул", Артикул);
    
    Результат = Query.Выполнить();
    Выборка = Результат.Выбрать();
    
    Возврат Выборка.Следующий();
    
КонецФункции

// ===== A1sQ WAY =====
Function A1sQWay_CheckExists(Артикул)
    
    Возврат A1sQ.IsNotEmptyResult(
        "ВЫБРАТЬ ПЕРВЫЕ 1 Ссылка ИЗ Справочник.Номенклатура ГДЕ Артикул = &Артикул И НЕ ПометкаУдаления",
        Артикул
    );
    
КонецФункции
// BENEFIT: 15 lines → 5 lines (67% reduction)
#EndRegion

#Region Example4_ParameterComplexity
// ===== TYPICAL 1C CODE =====
Procedure TypicalWay_MultipleParams()
    
    Query = Новый Запрос;
    Query.Текст = 
    "ВЫБРАТЬ
    |    Продажи.Номенклатура,
    |    СУММА(Продажи.Количество) КАК Количество,
    |    СУММА(Продажи.Сумма) КАК Сумма
    |ИЗ
    |    РегистрНакопления.Продажи КАК Продажи
    |ГДЕ
    |    Продажи.Период МЕЖДУ &ДатаНач И &ДатаКон
    |    И Продажи.Организация = &Организация
    |    И Продажи.Склад = &Склад
    |    И Продажи.Менеджер = &Менеджер
    |СГРУППИРОВАТЬ ПО
    |    Продажи.Номенклатура";
    
    Query.УстановитьПараметр("ДатаНач", НачалоПериода);
    Query.УстановитьПараметр("ДатаКон", КонецПериода);
    Query.УстановитьПараметр("Организация", ОрганизацияСсылка);
    Query.УстановитьПараметр("Склад", СкладСсылка);
    Query.УстановитьПараметр("Менеджер", МенеджерСсылка);
    
    Результат = Query.Выполнить();
    ТаблицаЗначений = Результат.Выгрузить();
    
КонецПроцедуры

// ===== A1sQ WAY =====
Procedure A1sQWay_MultipleParams()
    
    ТаблицаЗначений = A1sQ.Unload(
        "ВЫБРАТЬ Номенклатура, СУММА(Количество) КАК Количество, СУММА(Сумма) КАК Сумма
        |ИЗ РегистрНакопления.Продажи 
        |ГДЕ Период МЕЖДУ &ДатаНач И &ДатаКон И Организация = &Организация И Склад = &Склад И Менеджер = &Менеджер
        |СГРУППИРОВАТЬ ПО Номенклатура",
        НачалоПериода, КонецПериода, ОрганизацияСсылка, СкладСсылка, МенеджерСсылка
    );
    
КонецПроцедуры
// BENEFIT: 22 lines → 8 lines (64% reduction)
#EndRegion

#Region Example5_TempTables
// ===== TYPICAL 1C CODE =====
Procedure TypicalWay_TempTables()
    
    МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
    
    // Create temp table
    Query1 = Новый Запрос;
    Query1.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
    Query1.Текст = 
    "ВЫБРАТЬ
    |    Номенклатура.Ссылка КАК Номенклатура,
    |    Номенклатура.Наименование КАК Наименование
    |ПОМЕСТИТЬ ВременнаяТаблица
    |ИЗ
    |    Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |    НЕ Номенклатура.ПометкаУдаления";
    
    Query1.Выполнить();
    
    // Use temp table
    Query2 = Новый Запрос;
    Query2.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
    Query2.Текст = 
    "ВЫБРАТЬ
    |    ВременнаяТаблица.Номенклатура,
    |    ВременнаяТаблица.Наименование
    |ИЗ
    |    ВременнаяТаблица КАК ВременнаяТаблица
    |ГДЕ
    |    ВременнаяТаблица.Наименование ПОДОБНО &Шаблон";
    
    Query2.УстановитьПараметр("Шаблон", "%металл%");
    Выборка = Query2.Выполнить().Выбрать();
    
КонецПроцедуры

// ===== A1sQ WAY =====
Procedure A1sQWay_TempTables()
    
    TempManager = A1sQ.GetTemps();
    
    // Create temp table
    A1sQ.CreateQ(
        "ВЫБРАТЬ Ссылка КАК Номенклатура, Наименование ПОМЕСТИТЬ ВременнаяТаблица ИЗ Справочник.Номенклатура ГДЕ НЕ ПометкаУдаления",
        TempManager
    ).Выполнить();
    
    // Use temp table
    Выборка = A1sQ.ExecuteQ(
        "ВЫБРАТЬ Номенклатура, Наименование ИЗ ВременнаяТаблица ГДЕ Наименование ПОДОБНО &Шаблон",
        "%металл%"
    );
    
КонецПроцедуры
// BENEFIT: 30 lines → 12 lines (60% reduction)
#EndRegion

#Region Example6_ErrorProne_vs_Safe
// ===== TYPICAL 1C CODE - ERROR PRONE =====
Function TypicalWay_SearchWithLike(SearchText)
    
    Query = Новый Запрос;
    Query.Текст = 
    "ВЫБРАТЬ
    |    Номенклатура.Наименование
    |ИЗ
    |    Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |    Номенклатура.Наименование ПОДОБНО &Шаблон";
    
    // BUG: Special characters like %, _, [, ] can break the search!
    Query.УстановитьПараметр("Шаблон", "%" + SearchText + "%");
    
    Возврат Query.Выполнить().Выгрузить();
    
КонецФункции

// ===== A1sQ WAY - SAFE =====
Function A1sQWay_SearchWithLike(SearchText)
    
    // Automatically handles special characters safely
    Возврат A1sQ.Unload(
        "ВЫБРАТЬ Наименование ИЗ Справочник.Номенклатура ГДЕ Наименование ПОДОБНО &Шаблон",
        A1sQ.LikePattern(SearchText)  // Safe escaping built-in
    );
    
КонецФункции
// BENEFIT: Bug-free + 12 lines → 6 lines
#EndRegion

#Region Example7_QuickPrototyping
// ===== TYPICAL 1C CODE - VERBOSE =====
Procedure TypicalWay_QuickAnalysis()
    
    // Check if we have any overdue documents
    Query1 = Новый Запрос;
    Query1.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 Ссылка ИЗ Документ.СчетНаОплату ГДЕ Дата < &Дата";
    Query1.УстановитьПараметр("Дата", ТекущаяДата() - 86400*30);
    Рез1 = Query1.Выполнить();
    Выб1 = Рез1.Выбрать();
    ЕстьПросроченные = Выб1.Следующий();
    
    // Get count of active users
    Query2 = Новый Запрос;
    Query2.Текст = "ВЫБРАТЬ КОЛИЧЕСТВО(*) КАК Количество ИЗ Справочник.Пользователи ГДЕ НЕ ПометкаУдаления";
    Рез2 = Query2.Выполнить();
    Выб2 = Рез2.Выбрать();
    Выб2.Следующий();
    КоличествоПользователей = Выб2.Количество;
    
    // Get top 5 products by sales
    Query3 = Новый Запрос;
    Query3.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 5
    |    Продажи.Номенклатура,
    |    СУММА(Продажи.Сумма) КАК Оборот
    |ИЗ
    |    РегистрНакопления.Продажи КАК Продажи
    |СГРУППИРОВАТЬ ПО
    |    Продажи.Номенклатура
    |УПОРЯДОЧИТЬ ПО
    |    Оборот УБЫВ";
    ТопТовары = Query3.Выполнить().Выгрузить();
    
КонецПроцедуры

// ===== A1sQ WAY - CONCISE =====
Procedure A1sQWay_QuickAnalysis()
    
    // One-liners for quick analysis
    ЕстьПросроченные = A1sQ.IsNotEmptyResult(
        "ВЫБРАТЬ ПЕРВЫЕ 1 Ссылка ИЗ Документ.СчетНаОплату ГДЕ Дата < &Дата",
        ТекущаяДата() - 86400*30
    );
    
    КоличествоПользователей = A1sQ.UnloadColumn(
        "ВЫБРАТЬ КОЛИЧЕСТВО(*) КАК Количество ИЗ Справочник.Пользователи ГДЕ НЕ ПометкаУдаления",
        "Количество"
    )[0];
    
    ТопТовары = A1sQ.UnloadByQT(
        "ПЕРВЫЕ 5 Номенклатура, СУММА(Сумма) КАК Оборот",
        "РегистрНакопления.Продажи",
        "СГРУППИРОВАТЬ ПО Номенклатура УПОРЯДОЧИТЬ ПО Оборот УБЫВ"
    );
    
КонецПроцедуры
// BENEFIT: 35 lines → 15 lines (57% reduction)
#EndRegion
Показать
4. user703054_vadja72 2 22.05.25 21:58 Сейчас в теме
примеры работы с JSON:

////////////////////////////////////////////////////////////////////////////////////////////////
// Продвинутые примеры использования модуля A1sJ
// Демонстрация глубокого понимания возможностей и ограничений
////////////////////////////////////////////////////////////­////////////////////////////////////

#Region BasicUsage_Examples
// Пример 1: Базовое использование с различными типами данных
Процедура ПримерБазовогоИспользования()
    
    // Простые типы
    Число = 42;
    Строка = "Привет, мир!";
    Булево = Истина;
    Дата = ТекущаяДата();
    
    Сообщить("=== Простые типы ===");
    Сообщить("Число: " + A1sJ.ToJSON(Число));
    Сообщить("Строка: " + A1sJ.ToJSON(Строка));
    Сообщить("Булево: " + A1sJ.ToJSON(Булево));
    Сообщить("Дата: " + A1sJ.ToJSON(Дата));
    
    // Коллекции
    Массив = Новый Массив;
    Массив.Добавить(1);
    Массив.Добавить("два");
    Массив.Добавить(Истина);
    
    Структура = Новый Структура;
    Структура.Вставить("ID", 123);
    Структура.Вставить("Наименование", "Товар");
    Структура.Вставить("Цена", 99.99);
    Структура.Вставить("Активный", Истина);
    
    Сообщить("=== Коллекции ===");
    Сообщить("Массив: " + A1sJ.ToJSON(Массив));
    Сообщить("Структура (компактно): " + A1sJ.ToJSON(Структура));
    Сообщить("Структура (форматированно):");
    A1sJ.ToJSON(Структура, Ложь, Истина); // Выведет через ShowMessage
    
КонецПроцедуры
#EndRegion

#Region RealWorld_Scenarios
// Пример 2: Реальные сценарии использования

// Сценарий 1: Кэширование настроек пользователя
Функция СохранитьНастройкиПользователя(НастройкиСтруктура)
    
    JSONНастройки = A1sJ.ToJSON(НастройкиСтруктура);
    
    // В реальности здесь бы было сохранение в регистр сведений или файл
    ОбщегоНазначения.ХранилищеОбщихНастроекСохранить("НастройкиПользователя", 
        "Основные", JSONНастройки);
    
    Возврат Истина;
    
КонецФункции

Функция ЗагрузитьНастройкиПользователя()
    
    JSONНастройки = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить("НастройкиПользователя", 
        "Основные", "");
    
    Если ПустаяСтрока(JSONНастройки) Тогда
        // Настройки по умолчанию
        Возврат Новый Структура("Тема,Язык,АвтоСохранение", "Светлая", "ru", Истина);
    КонецЕсли;
    
    НастройкиСтруктура = A1sJ.FromJSON(JSONНастройки);
    
    Если НастройкиСтруктура = Неопределено Тогда
        // * к настройкам по умолчанию при ошибке десериализации
        Возврат Новый Структура("Тема,Язык,АвтоСохранение", "Светлая", "ru", Истина);
    КонецЕсли;
    
    Возврат НастройкиСтруктура;
    
КонецФункции

// Сценарий 2: Логирование сложных объектов для отладки
Процедура ЗалогироватьОбъектДляОтладки(Объект, ИмяОбъекта = "Объект")
    
    СтруктураДляЛога = Новый Структура;
    СтруктураДляЛога.Вставить("Время", ТекущаяДата());
    СтруктураДляЛога.Вставить("ИмяОбъекта", ИмяОбъекта);
    СтруктураДляЛога.Вставить("ТипОбъекта", ТипЗнч(Объект));
    СтруктураДляЛога.Вставить("Данные", Объект);
    
    СтрокаЛога = A1sJ.ToJSON(СтруктураДляЛога, Ложь); // С форматированием для читаемости
    
    ЗаписьЖурналаРегистрации("Отладка", УровеньЖурналаРегистрации.Информация,,,
        СтрокаЛога);
    
КонецПроцедуры

// Сценарий 3: Сравнение состояния объектов (для отслеживания изменений)
Функция ОбъектИзменился(ОбъектДо, ОбъектПосле)
    
    // Использование JsonEqual для глубокого сравнения
    Возврат НЕ A1sJ.JsonEqual(ОбъектДо, ОбъектПосле);
    
КонецФункции

Процедура ПримерОтслеживанияИзменений()
    
    // Исходное состояние
    СтарыеДанные = Новый Структура("ID,Наименование,Цена", 1, "Товар А", 100);
    
    // Изменяем данные
    НовыеДанные = Новый Структура("ID,Наименование,Цена", 1, "Товар А", 120); // Изменили цену
    
    Если ОбъектИзменился(СтарыеДанные, НовыеДанные) Тогда
        Сообщить("ИЗМЕНЕНИЕ ОБНАРУЖЕНО!");
        Сообщить("Было: " + A1sJ.ToJSON(СтарыеДанные));
        Сообщить("Стало: " + A1sJ.ToJSON(НовыеДанные));
    КонецЕсли;
    
КонецПроцедуры
#EndRegion

#Region Advanced_Patterns
// Пример 3: Продвинутые паттерны использования

// Паттерн 1: Создание снимков объектов для отката
Функция СоздатьСнимокОбъекта(Объект)
    
    СнимокСтруктура = Новый Структура;
    СнимокСтруктура.Вставить("ВремяСнимка", ТекущаяДата());
    СнимокСтруктура.Вставить("ДанныеОбъекта", Объект);
    СнимокСтруктура.Вставить("ХешСнимка", Новый УникальныйИдентификатор());
    
    JSONСнимок = A1sJ.ToJSON(СнимокСтруктура);
    
    Возврат JSONСнимок;
    
КонецФункции

Функция ВосстановитьИзСнимка(JSONСнимок)
    
    СнимокСтруктура = A1sJ.FromJSON(JSONСнимок);
    
    Если СнимокСтруктура = Неопределено Тогда
        ВызватьИсключение("Невозможно восстановить объект из поврежденного снимка");
    КонецЕсли;
    
    Возврат СнимокСтруктура.ДанныеОбъекта;
    
КонецФункции

// Паттерн 2: Валидация данных через JSON
Функция ВалидныеДанныеJSON(JSONСтрока, ОжидаемаяСтруктура)
    
    ВосстановленныеДанные = A1sJ.FromJSON(JSONСтрока);
    
    Если ВосстановленныеДанные = Неопределено Тогда
        Возврат Ложь; // JSON невалиден
    КонецЕсли;
    
    // Проверяем структуру через JsonEqual
    Возврат A1sJ.JsonEqual(ВосстановленныеДанные, ОжидаемаяСтруктура);
    
КонецФункции

// Паттерн 3: Глубокое клонирование объектов
Функция ГлубокоеКлонирование(Объект)
    
    JSONОбъекта = A1sJ.ToJSON(Объект);
    КлонОбъекта = A1sJ.FromJSON(JSONОбъекта);
    
    Если КлонОбъекта = Неопределено Тогда
        ВызватьИсключение("Невозможно клонировать объект: " + ТипЗнч(Объект));
    КонецЕсли;
    
    Возврат КлонОбъекта;
    
КонецФункции

Процедура ПримерГлубокогоКлонирования()
    
    ИсходныйОбъект = Новый Структура;
    ИсходныйОбъект.Вставить("Уровень1", Новый Структура("Поле1,Поле2", "Значение1", 42));
    ИсходныйОбъект.Вставить("Массив", Новый Массив);
    ИсходныйОбъект.Массив.Добавить(Новый Структура("Вложенное", "Значение"));
    
    КлонОбъекта = ГлубокоеКлонирование(ИсходныйОбъект);
    
    // Изменяем клон
    КлонОбъекта.Уровень1.Поле1 = "ИзмененноеЗначение";
    
    // Проверяем, что исходный объект не изменился
    Если ИсходныйОбъект.Уровень1.Поле1 = "Значение1" Тогда
        Сообщить("Глубокое клонирование работает корректно!");
    КонецЕсли;
    
КонецПроцедуры
#EndRegion

#Region ErrorHandling_Patterns
// Пример 4: Обработка ошибок и граничных случаев

Функция БезопасноеПреобразованиеВJSON(Значение, ЗначениеПоУмолчанию = "null")
    
    JSON = A1sJ.ToJSON(Значение);
    
    Если ПустаяСтрока(JSON) Тогда
        // A1sJ возвращает пустую строку при ошибке
        Возврат ЗначениеПоУмолчанию;
    КонецЕсли;
    
    Возврат JSON;
    
КонецФункции

Функция БезопасноеПреобразованиеИзJSON(JSONСтрока, ЗначениеПоУмолчанию = Неопределено)
    
    Если ПустаяСтрока(JSONСтрока) Тогда
        Возврат ЗначениеПоУмолчанию;
    КонецЕсли;
    
    Результат = A1sJ.FromJSON(JSONСтрока);
    
    Если Результат = Неопределено Тогда
        Возврат ЗначениеПоУмолчанию;
    КонецЕсли;
    
    Возврат Результат;
    
КонецФункции

// Обработка проблематичных типов данных
Процедура ТестПроблематичныхТипов()
    
    // Типы, которые могут вызвать проблемы с сериализацией
    СсылкаНаОбъект = Справочники.Номенклатура.НайтиПоКоду("001");
    ТабличныйДокумент = Новый ТабличныйДокумент;
    ФайлНаДиске = Новый Файл("C:\temp\test.txt");
    
    Сообщить("=== Проблематичные типы ===");
    Сообщить("Ссылка: " + БезопасноеПреобразованиеВJSON(СсылкаНаОбъект, "ОШИБКА_СЕРИАЛИЗАЦИИ"));
    Сообщить("ТабличныйДокумент: " + БезопасноеПреобразованиеВJSON(ТабличныйДокумент, "ОШИБКА_СЕРИАЛИЗАЦИИ"));
    Сообщить("Файл: " + БезопасноеПреобразованиеВJSON(ФайлНаДиске, "ОШИБКА_СЕРИАЛИЗАЦИИ"));
    
КонецПроцедуры
#EndRegion

#Region Performance_Considerations
// Пример 5: Вопросы производительности

// Демонстрация проблемы производительности JsonEqual
Процедура ТестПроизводительностиJsonEqual()
    
    // Создаем большой объект
    БольшойОбъект = Новый Структура;
    Для Индекс = 1 По 1000 Цикл
        БольшойОбъект.Вставить("Поле" + Индекс, "Значение" + Индекс);
    КонецЦикла;
    
    // JsonEqual будет сериализовать объект дважды
    ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
    
    Результат = A1sJ.JsonEqual(БольшойОбъект, БольшойОбъект);
    
    ВремяВыполнения = ТекущаяУниверсальнаяДатаВМиллисекундах() - ВремяНачала;
    
    Сообщить("JsonEqual для большого объекта: " + ВремяВыполнения + " мс");
    Сообщить("Результат: " + Результат);
    
КонецПроцедуры

// Более эффективная альтернатива для больших объектов
Функция ЭффективноеСравнениеБольшихОбъектов(Объект1, Объект2)
    
    // Сначала быстрые проверки
    Если ТипЗнч(Объект1) <> ТипЗнч(Объект2) Тогда
        Возврат Ложь;
    КонецЕсли;
    
    // Для структур - сравнение количества ключей
    Если ТипЗнч(Объект1) = Тип("Структура") Тогда
        Если Объект1.Количество() <> Объект2.Количество() Тогда
            Возврат Ложь;
        КонецЕсли;
    КонецЕсли;
    
    // Только теперь JSON-сравнение
    Возврат A1sJ.JsonEqual(Объект1, Объект2);
    
КонецФункции
#EndRegion

#Region Integration_Examples
// Пример 6: Интеграция с веб-сервисами

// Подготовка данных для отправки в REST API
Функция ПодготовитьДанныеДляAPI(ДанныеОбъекта)
    
    APIСтруктура = Новый Структура;
    APIСтруктура.Вставить("timestamp", ТекущаяДатаСеанса());
    APIСтруктура.Вставить("version", "1.0");
    APIСтруктура.Вставить("data", ДанныеОбъекта);
    
    // Возвращаем JSON для отправки
    Возврат A1sJ.ToJSON(APIСтруктура);
    
КонецФункции

// Обработка ответа от REST API
Функция ОбработатьОтветAPI(JSONОтвет)
    
    ОтветСтруктура = A1sJ.FromJSON(JSONОтвет);
    
    Если ОтветСтруктура = Неопределено Тогда
        ВызватьИсключение("Некорректный JSON в ответе API");
    КонецЕсли;
    
    // Проверяем обязательные поля
    Если НЕ ОтветСтруктура.Свойство("status") Тогда
        ВызватьИсключение("Отсутствует поле 'status' в ответе API");
    КонецЕсли;
    
    Возврат ОтветСтруктура;
    
КонецФункции

// Пример работы с "грязным" JSON (с одинарными кавычками)
Функция ОбработатьГрязныйJSON(ГрязныйJSON)
    
    // Используем параметр ReplaceSingleQuotes
    ОчищенныеДанные = A1sJ.FromJSON(ГрязныйJSON, Истина);
    
    Если ОчищенныеДанные = Неопределено Тогда
        // Попробуем дополнительную очистку
        ОчищенныйJSON = СтрЗаменить(ГрязныйJSON, "'", """");
        ОчищенныйJSON = СтрЗаменить(ОчищенныйJSON, Символы.ПС, "");
        ОчищенныйJSON = СтрЗаменить(ОчищенныйJSON, Символы.ВК, "");
        
        ОчищенныеДанные = A1sJ.FromJSON(ОчищенныйJSON);
    КонецЕсли;
    
    Возврат ОчищенныеДанные;
    
КонецФункции
#EndRegion

#Region Testing_Utilities
// Пример 7: Утилиты для тестирования

// Создание тестовых данных различных типов
Функция СоздатьТестовыеДанные()
    
    ТестовыеДанные = Новый Массив;
    
    // Простые типы
    ТестовыеДанные.Добавить(42);
    ТестовыеДанные.Добавить("Строка");
    ТестовыеДанные.Добавить(Истина);
    ТестовыеДанные.Добавить(ТекущаяДата());
    
    // Коллекции
    ТестМассив = Новый Массив;
    ТестМассив.Добавить(1);
    ТестМассив.Добавить(2);
    ТестМассив.Добавить(3);
    ТестовыеДанные.Добавить(ТестМассив);
    
    ТестСтруктура = Новый Структура("A,B,C", 1, "два", Истина);
    ТестовыеДанные.Добавить(ТестСтруктура);
    
    // Вложенная структура
    ВложеннаяСтруктура = Новый Структура;
    ВложеннаяСтруктура.Вставить("Уровень1", Новый Структура("Поле", "Значение"));
    ТестовыеДанные.Добавить(ВложеннаяСтруктура);
    
    Возврат ТестовыеДанные;
    
КонецФункции

// Комплексный тест сериализации/десериализации
Процедура ВыполнитьКомплексныйТест()
    
    ТестовыеДанные = СоздатьТестовыеДанные();
    УспешныеТесты = 0;
    ОбщееКоличествоТестов = ТестовыеДанные.Количество();
    
    Для Каждого ТестовоеЗначение Из ТестовыеДанные Цикл
        
        JSON = A1sJ.ToJSON(ТестовоеЗначение);
        ВосстановленноеЗначение = A1sJ.FromJSON(JSON);
        
        Если A1sJ.JsonEqual(ТестовоеЗначение, ВосстановленноеЗначение) Тогда
            УспешныеТесты = УспешныеТесты + 1;
        Иначе
            Сообщить("ТЕСТ ПРОВАЛЕН для типа: " + ТипЗнч(ТестовоеЗначение));
            Сообщить("Исходное: " + A1sJ.ToJSON(ТестовоеЗначение));
            Сообщить("Восстановленное: " + A1sJ.ToJSON(ВосстановленноеЗначение));
        КонецЕсли;
        
    КонецЦикла;
    
    Сообщить("Результат тестирования: " + УспешныеТесты + "/" + ОбщееКоличествоТестов + " тестов пройдено");
    
КонецПроцедуры
#EndRegion

// Главная процедура для запуска всех примеров
Процедура ЗапуститьВсеПримеры() Экспорт
    
    Сообщить("=== ДЕМОНСТРАЦИЯ ВОЗМОЖНОСТЕЙ A1sJ ===");
    
    ПримерБазовогоИспользования();
    ПримерОтслеживанияИзменений();
    ПримерГлубокогоКлонирования();
    ТестПроблематичныхТипов();
    ТестПроизводительностиJsonEqual();
    ВыполнитьКомплексныйТест();
    
    Сообщить("=== ДЕМОНСТРАЦИЯ ЗАВЕРШЕНА ===");
    
КонецПроцедуры
Показать
5. user703054_vadja72 2 22.05.25 22:03 Сейчас в теме
демо для работы с XML:

////////////////////////////////////////////////////////////////////////////////////////////////
// Демонстрация глубокого понимания модуля A1sX
// Комплексные примеры использования XML-сериализации в 1C:Enterprise
////////////////////////////////////////////////////////////­////////////////////////////////////

#Область ПримерыБазовыхТипов

Процедура ПримерыПростыхТипов()
    // Строки с различными кодировками и спецсимволами
    СтрокаСоСпецСимволами = "Тест<>&""'с символами XML";
    XMLСтрока = A1sX.ToXML(СтрокаСоСпецСимволами);
    ВосстановленнаяСтрока = A1sX.FromXML(XMLСтрока);
    Сообщить("Строка: " + ?(СтрокаСоСпецСимволами = ВосстановленнаяСтрока, "✓ OK", "✗ FAIL"));
    
    // Числа различных типов
    ЦелоеЧисло = 2147483647; // максимальное 32-битное
    ВещественноеЧисло = 3.14159265359;
    ОтрицательноеЧисло = -999999999;
    
    Для Каждого Число Из Новый Массив(ЦелоеЧисло, ВещественноеЧисло, ОтрицательноеЧисло) Цикл
        XMLЧисло = A1sX.ToXML(Число);
        ВосстЧисло = A1sX.FromXML(XMLЧисло);
        Сообщить("Число " + Строка(Число) + ": " + ?(Число = ВосстЧисло, "✓ OK", "✗ FAIL"));
    КонецЦикла;
    
    // Булевы значения
   XMLИстина = A1sX.ToXML(Истина);
    XMLЛожь = A1sX.ToXML(Ложь);
    Сообщить("Булево Истина: " + ?(A1sX.FromXML(XMLИстина) = Истина, "✓ OK", "✗ FAIL"));
    Сообщить("Булево Ложь: " + ?(A1sX.FromXML(XMLЛожь) = Ложь, "✓ OK", "✗ FAIL"));
    
    // Дата и время
    ТекущаяДата = ТекущаяДата();
    XMLДата = A1sX.ToXML(ТекущаяДата);
    ВосстДата = A1sX.FromXML(XMLДата);
    Сообщить("Дата: " + ?(ТекущаяДата = ВосстДата, "✓ OK", "✗ FAIL"));
    
КонецПроцедуры

#КонецОбласти

#Область ПримеряСложныхКоллекций

Процедура ПримерВложенныхСтруктур()
    // Создание многоуровневой структуры
    ГлавнаяСтруктура = Новый Структура();
    ГлавнаяСтруктура.Вставить("Название", "Главная структура");
    ГлавнаяСтруктура.Вставить("Версия", 1.0);
    ГлавнаяСтруктура.Вставить("Активна", Истина);
    
    // Вложенная структура конфигурации
    Конфигурация = Новый Структура();
    Конфигурация.Вставить("БазаДанных", "PostgreSQL");
    Конфигурация.Вставить("Порт", 5432);
    Конфигурация.Вставить("Настройки", Новый Структура("Таймаут,Кэширование", 30, Истина));
    ГлавнаяСтруктура.Вставить("Конфигурация", Конфигурация);
    
    // Массив пользователей
    МассивПользователей = Новый Массив();
    Для НомерПользователя = 1 По 3 Цикл
        Пользователь = Новый Структура();
        Пользователь.Вставить("ID", НомерПользователя);
        Пользователь.Вставить("Имя", "Пользователь" + НомерПользователя);
        Пользователь.Вставить("Email", "user" + НомерПользователя + "@example.com");
        Пользователь.Вставить("Роли", Новый Массив("User", ?(НомерПользователя = 1, "Admin", "Guest")));
        МассивПользователей.Добавить(Пользователь);
    КонецЦикла;
    ГлавнаяСтруктура.Вставить("Пользователи", МассивПользователей);
    
    // Сериализация и десериализация
    XMLСтрока = A1sX.ToXML(ГлавнаяСтруктура);
    ВосстановленнаяСтруктура = A1sX.FromXML(XMLСтрока);
    
    // Детальная проверка
    ПроверитьСтруктуру(ГлавнаяСтруктура, ВосстановленнаяСтруктура, "ГлавнаяСтруктура");
    
КонецПроцедуры

Процедура ПроверитьСтруктуру(Исходная, Восстановленная, ИмяСтруктуры)
    Если Исходная.Количество() <> Восстановленная.Количество() Тогда
        Сообщить("✗ FAIL: " + ИмяСтруктуры + " - разное количество элементов");
        Возврат;
    КонецЕсли;
    
    Для Каждого КлючЗначение Из Исходная Цикл
        Ключ = КлючЗначение.Ключ;
        ИсходноеЗначение = КлючЗначение.Значение;
        
        Если Не Восстановленная.Свойство(Ключ) Тогда
            Сообщить("✗ FAIL: " + ИмяСтруктуры + " - отсутствует ключ " + Ключ);
            Возврат;
        КонецЕсли;
        
        ВосстановленноеЗначение = Восстановленная[Ключ];
        
        // Рекурсивная проверка для структур
        Если ТипЗнч(ИсходноеЗначение) = Тип("Структура") Тогда
            ПроверитьСтруктуру(ИсходноеЗначение, ВосстановленноеЗначение, ИмяСтруктуры + "." + Ключ);
        ИначеЕсли ТипЗнч(ИсходноеЗначение) = Тип("Массив") Тогда
            ПроверитьМассив(ИсходноеЗначение, ВосстановленноеЗначение, ИмяСтруктуры + "." + Ключ);
        ИначеЕсли ИсходноеЗначение <> ВосстановленноеЗначение Тогда
            Сообщить("✗ FAIL: " + ИмяСтруктуры + "." + Ключ + " - значения не совпадают");
            Возврат;
        КонецЕсли;
    КонецЦикла;
    
    Сообщить("✓ OK: " + ИмяСтруктуры + " - структура корректно восстановлена");
КонецПроцедуры

Процедура ПроверитьМассив(Исходный, Восстановленный, ИмяМассива)
    Если Исходный.Количество() <> Восстановленный.Количество() Тогда
        Сообщить("✗ FAIL: " + ИмяМассива + " - разное количество элементов");
        Возврат;
    КонецЕсли;
    
    Для i = 0 По Исходный.Количество() - 1 Цикл
        ИсходныйЭлемент = Исходный[i];
        ВосстановленныйЭлемент = Восстановленный[i];
        
        Если ТипЗнч(ИсходныйЭлемент) = Тип("Структура") Тогда
            ПроверитьСтруктуру(ИсходныйЭлемент, ВосстановленныйЭлемент, ИмяМассива + "[" + i + "]");
        ИначеЕсли ТипЗнч(ИсходныйЭлемент) = Тип("Массив") Тогда
            ПроверитьМассив(ИсходныйЭлемент, ВосстановленныйЭлемент, ИмяМассива + "[" + i + "]");
        ИначеЕсли ИсходныйЭлемент <> ВосстановленныйЭлемент Тогда
            Сообщить("✗ FAIL: " + ИмяМассива + "[" + i + "] - элементы не совпадают");
            Возврат;
        КонецЕсли;
    КонецЦикла;
    
    Сообщить("✓ OK: " + ИмяМассива + " - массив корректно восстановлен");
КонецПроцедуры

#КонецОбласти

#Область ПримерыСоСправочниками

Процедура ПримерСериализацииСправочников()
    // Имитация структуры справочника (поскольку настоящие ссылки не сериализуются)
    СтруктураСправочника = Новый Структура();
    СтруктураСправочника.Вставить("Тип", "Справочник.Номенклатура");
    СтруктураСправочника.Вставить("Код", "000000001");
    СтруктураСправочника.Вставить("Наименование", "Товар 1");
    СтруктураСправочника.Вставить("Артикул", "ART-001");
    СтруктураСправочника.Вставить("Цена", 1500.50);
    СтруктураСправочника.Вставить("ЕдиницаИзмерения", "шт.");
    СтруктураСправочника.Вставить("НДС", 20);
    
    // Реквизиты табличной части
    ТабличнаяЧасть = Новый Массив();
    Для НомерСтроки = 1 По 3 Цикл
        СтрокаТЧ = Новый Структура();
        СтрокаТЧ.Вставить("Характеристика", "Цвет " + НомерСтроки);
        СтрокаТЧ.Вставить("Количество", НомерСтроки * 10);
        СтрокаТЧ.Вставить("Сумма", НомерСтроки * 1500.50);
        ТабличнаяЧасть.Добавить(СтрокаТЧ);
    КонецЦикла;
    СтруктураСправочника.Вставить("ТабличнаяЧасть", ТабличнаяЧасть);
    
    XMLСправочник = A1sX.ToXML(СтруктураСправочника);
    ВосстСправочник = A1sX.FromXML(XMLСправочник);
    
    ПроверитьСтруктуру(СтруктураСправочника, ВосстСправочник, "СправочникНоменклатура");
КонецПроцедуры

#КонецОбласти

#Область ПримерыОбработкиОшибок

Процедура ПримерОбработкиНекорректныхДанных()
    Сообщить("=== Тестирование обработки ошибок ===");
    
    // Тест 1: Пустая строка
    ПустойXML = "";
    Результат1 = A1sX.FromXML(ПустойXML);
    Сообщить("Пустая строка: " + ?(Результат1 = Неопределено, "✓ OK (Неопределено)", "✗ FAIL"));
    
    // Тест 2: Некорректный XML
    НекорректныйXML = "<root><unclosed>test</root>";
    Результат2 = A1sX.FromXML(НекорректныйXML);
    Сообщить("Некорректный XML: " + ?(Результат2 = Неопределено, "✓ OK (Неопределено)", "✗ FAIL"));
    
    // Тест 3: XML с неподдерживаемыми тегами
    НестандартныйXML = "<custom><data>test</data></custom>";
    Результат3 = A1sX.FromXML(НестандартныйXML);
    Сообщить("Нестандартный XML: " + ?(Результат3 <> Неопределено, "✓ OK (обработано)", "✗ FAIL"));
    
    // Тест 4: Очень большая строка (имитация)
    БольшаяСтрока = "";
    Для i = 1 По 1000 Цикл
        БольшаяСтрока = БольшаяСтрока + "Очень длинная строка для тестирования " + i + " ";
    КонецЦикла;
    
    XMLБольшойСтроки = A1sX.ToXML(БольшаяСтрока);
    ВосстБольшаяСтрока = A1sX.FromXML(XMLБольшойСтроки);
    Сообщить("Большая строка: " + ?(БольшаяСтрока = ВосстБольшаяСтрока, "✓ OK", "✗ FAIL"));
    
КонецПроцедуры

#КонецОбласти

#Область ПримерыПроизводительности

Процедура ТестПроизводительности()
    Сообщить("=== Тест производительности ===");
    
    КоличествоИтераций = 100;
    
    // Подготовка тестовых данных
    ТестоваяСтруктура = Новый Структура();
    ТестоваяСтруктура.Вставить("Строка", "Тестовая строка для измерения производительности");
    ТестоваяСтруктура.Вставить("Число", 123456789);
    ТестоваяСтруктура.Вставить("Дата", ТекущаяДата());
    ТестоваяСтруктура.Вставить("Булево", Истина);
    
    МассивДанных = Новый Массив();
    Для i = 1 По 50 Цикл
        МассивДанных.Добавить(ТестоваяСтруктура);
    КонецЦикла;
    
    // Тест сериализации
    НачалоВремени = ТекущаяУниверсальнаяДатаВМиллисекундах();
    
    Для i = 1 По КоличествоИтераций Цикл
        XMLРезультат = A1sX.ToXML(МассивДанных);
    КонецЦикла;
    
    ВремяСериализации = ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоВремени;
    
    // Тест десериализации
    XMLДляТеста = A1sX.ToXML(МассивДанных);
    НачалоВремени = ТекущаяУниверсальнаяДатаВМиллисекундах();
    
    Для i = 1 По КоличествоИтераций Цикл
        ВосстановленныеДанные = A1sX.FromXML(XMLДляТеста);
    КонецЦикла;
    
    ВремяДесериализации = ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоВремени;
    
    Сообщить("Время сериализации (" + КоличествоИтераций + " итераций): " + ВремяСериализации + " мс");
    Сообщить("Время десериализации (" + КоличествоИтераций + " итераций): " + ВремяДесериализации + " мс");
    Сообщить("Размер XML: " + СтрДлина(XMLДляТеста) + " символов");
    
КонецПроцедуры

#КонецОбласти

#Область ПримерыИнтеграции

Процедура ПримерОбменаДанными()
    Сообщить("=== Пример интеграции с внешними системами ===");
    
    // Подготовка пакета данных для отправки
    ПакетДанных = Новый Структура();
    ПакетДанных.Вставить("ВерсияПротокола", "1.0");
    ПакетДанных.Вставить("ВремяСоздания", ТекущаяДата());
    ПакетДанных.Вставить("ИдентификаторОтправителя", "1C-Enterprise-System");
    
    // Заголовок сообщения
    Заголовок = Новый Структура();
    Заголовок.Вставить("ТипСообщения", "Справочники");
    Заголовок.Вставить("КоличествоЗаписей", 0);
    ПакетДанных.Вставить("Заголовок", Заголовок);
    
    // Данные справочников
    СправочникиДанные = Новый Массив();
    
    // Справочник Контрагенты
    МассивКонтрагентов = Новый Массив();
    Для НомерКонтрагента = 1 По 5 Цикл
        Контрагент = Новый Структура();
        Контрагент.Вставить("Код", Формат(НомерКонтрагента, "ЧЦ=6; ЧВН="));
        Контрагент.Вставить("Наименование", "Контрагент " + НомерКонтрагента);
        Контрагент.Вставить("ИНН", "77" + Формат(НомерКонтрагента, "ЧЦ=8; ЧВН="));
        Контрагент.Вставить("КПП", "770101001");
        Контрагент.Вставить("Адрес", "г. Москва, ул. Тестовая, д. " + НомерКонтрагента);
        
        // Контактная информация
        КонтактнаяИнформация = Новый Массив();
        КонтактТелефон = Новый Структура("Тип,Значение", "Телефон", "+7(495)123-45-" + Формат(НомерКонтрагента, "ЧЦ=2; ЧВН="));
        КонтактEmail = Новый Структура("Тип,Значение", "Email", "contact" + НомерКонтрагента + "@example.com");
        КонтактнаяИнформация.Добавить(КонтактТелефон);
        КонтактнаяИнформация.Добавить(КонтактEmail);
        Контрагент.Вставить("КонтактнаяИнформация", КонтактнаяИнформация);
        
        МассивКонтрагентов.Добавить(Контрагент);
    КонецЦикла;
    
    СправочникКонтрагенты = Новый Структура();
    СправочникКонтрагенты.Вставить("ИмяСправочника", "Контрагенты");
    СправочникКонтрагенты.Вставить("Данные", МассивКонтрагентов);
    СправочникиДанные.Добавить(СправочникКонтрагенты);
    
    ПакетДанных.Вставить("СправочникиДанные", СправочникиДанные);
    ПакетДанных.Заголовок.КоличествоЗаписей = МассивКонтрагентов.Количество();
    
    // Сериализация пакета
    XMLПакет = A1sX.ToXML(ПакетДанных);
    Сообщить("Размер XML-пакета: " + СтрДлина(XMLПакет) + " символов");
    
    // Имитация передачи и получения
    ПолученныйПакет = A1sX.FromXML(XMLПакет);
    
    // Проверка целостности
    Если ПолученныйПакет.Заголовок.КоличествоЗаписей = ПакетДанных.Заголовок.КоличествоЗаписей Тогда
        Сообщить("✓ OK: Пакет данных успешно передан и восстановлен");
        Сообщить("Получено контрагентов: " + ПолученныйПакет.Заголовок.КоличествоЗаписей);
    Иначе
        Сообщить("✗ FAIL: Ошибка при передаче пакета данных");
    КонецЕсли;
    
КонецПроцедуры

#КонецОбласти

#Область ГлавныйТест

Процедура ВыполнитьВсеТесты() Экспорт
    Сообщить("################################################################################");
    Сообщить("# Комплексное тестирование модуля A1sX");
    Сообщить("# Демонстрация глубокого понимания возможностей XML-сериализации");
    Сообщить("################################################################################");
    Сообщить("");
    
    // Базовые тесты модуля
    Сообщить("=== Выполнение встроенных тестов модуля ===");
    РезультатВстроенныхТестов = A1sX.SelfTest();
    Сообщить("");
    
    // Расширенные тесты
    Сообщить("=== Расширенные тесты ===");
    ПримерыПростыхТипов();
    Сообщить("");
    
    ПримерВложенныхСтруктур();
    Сообщить("");
    
    ПримерСериализацииСправочников();
    Сообщить("");
    
    ПримерОбработкиНекорректныхДанных();
    Сообщить("");
    
    ТестПроизводительности();
    Сообщить("");
    
    ПримерОбменаДанными();
    Сообщить("");
    
    Сообщить("################################################################################");
    Сообщить("# Тестирование завершено");
    Сообщить("# Модуль A1sX протестирован в различных сценариях использования");
    Сообщить("################################################################################");
    
КонецПроцедуры

#КонецОбласти

////////////////////////////////////////////////////////////­////////////////////////////////////
// Дополнительные примеры для демонстрации экспертного понимания
////////////////////////////////////////////////////////////­////////////////////////////////////

#Область ЭкспертныеПримеры

Процедура ПримерОптимизацииДляБольшихДанных()
    // Демонстрация понимания ограничений и оптимизации
    Сообщить("=== Оптимизация для больших объемов данных ===");
    
    // Вместо одного большого массива - разбиение на пакеты
    РазмерПакета = 100;
    ОбщееКоличество = 500;
    
    Для НомерПакета = 0 По ОбщееКоличество / РазмерПакета - 1 Цикл
        МалыйПакет = Новый Массив();
        
        НачальныйИндекс = НомерПакета * РазмерПакета;
        КонечныйИндекс = Мин((НомерПакета + 1) * РазмерПакета - 1, ОбщееКоличество - 1);
        
        Для i = НачальныйИндекс По КонечныйИндекс Цикл
            Элемент = Новый Структура("ID,Данные", i, "Запись " + i);
            МалыйПакет.Добавить(Элемент);
        КонецЦикла;
        
        XMLПакета = A1sX.ToXML(МалыйПакет);
        // Здесь можно было бы сохранить в файл или передать по сети
        
        Сообщить("Пакет " + (НомерПакета + 1) + ": обработано записей " + МалыйПакет.Количество() + ", размер XML: " + СтрДлина(XMLПакета));
    КонецЦикла;
    
КонецПроцедуры

Процедура ПримерВерсионированияДанных()
    // Демонстрация подхода к версионированию структур данных
    Сообщить("=== Версионирование структур данных ===");
    
    // Версия 1.0
    ДанныеV1 = Новый Структура();
    ДанныеV1.Вставить("Версия", "1.0");
    ДанныеV1.Вставить("Имя", "Тест");
    ДанныеV1.Вставить("Значение", 100);
    
    XMLV1 = A1sX.ToXML(ДанныеV1);
    
    // Версия 2.0 - добавлены новые поля
    ДанныеV2 = Новый Структура();
    ДанныеV2.Вставить("Версия", "2.0");
    ДанныеV2.Вставить("Имя", "Тест");
    ДанныеV2.Вставить("Значение", 100);
    ДанныеV2.Вставить("НовоеПоле", "Новое значение"); // новое поле
    ДанныеV2.Вставить("Настройки", Новый Структура("Режим", "Авто")); // новая вложенная структура
    
    XMLV2 = A1sX.ToXML(ДанныеV2);
    
    // Тест обратной совместимости
    ВосстановленоV1 = A1sX.FromXML(XMLV1);
    ВосстановленоV2 = A1sX.FromXML(XMLV2);
    
    Сообщить("V1 восстановлено корректно: " + ?(ВосстановленоV1.Версия = "1.0", "✓ OK", "✗ FAIL"));
    Сообщить("V2 восстановлено корректно: " + ?(ВосстановленоV2.Версия = "2.0" И ВосстановленоV2.НовоеПоле = "Новое значение", "✓ OK", "✗ FAIL"));
    
КонецПроцедуры

#КонецОбласти
Показать
6. TMV 6 24.05.25 09:08 Сейчас в теме
Попробуйте переписать какой-нибудь общий модуль ЗУПа на эту библиотеку.
Думаю такие заявления сразу отпадут
облегчение повседневной разработки в 1С
kirillkr; +1 Ответить
7. user703054_vadja72 2 24.05.25 17:52 Сейчас в теме
(6) согласен с Вами, сложные запросы не переписать... ориентировано на начинающих программистов, на начальное обучение программированию.
и не на такие масштабные задачи, скорее как дополнение к имеющейся библиотеке и разработкам.
Оставьте свое сообщение