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

20.05.25

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

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

Бесплатные

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

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

 

Библиотека 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    217065    1188    413    

1054

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

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

14400 руб.

20.08.2024    43004    234    123    

218

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

Расширение для создания и редактирования печатных форм в системе 1С:Предприятие 8.3. Благодаря конструктору можно значительно снизить затраты времени на разработку печатных форм, повысить качество и прозрачность разработки, а также навести порядок в многообразии корпоративных печатных форм.

22200 руб.

06.10.2023    27525    71    30    

101

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

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

9500 руб.

17.05.2024    39015    141    57    

178

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

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

16000 руб.

10.11.2023    19463    76    39    

92

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

Первые попытки разработки на 1С с использованием больших языковых моделей (LLM) могут разочаровать. LLMки сильно галлюцинируют, потому что не знают устройства конфигураций 1С, не знают нюансов синтаксиса. Но если дать им подсказки с помощью MCP, то результат получается кардинально лучше. Далее в публикации: MCP для поиска по метаданым 1С, справке синтакс-помошника и проверки синтаксиса.

9900 руб.

25.08.2025    8668    14    7    

24

Инструментарий разработчика 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    2512    2    0    

8
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Adeptus 247 22.05.25 15:49 Сейчас в теме
2. user703054_vadja72 1 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 1 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 1 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 1 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 3 24.05.25 09:08 Сейчас в теме
Попробуйте переписать какой-нибудь общий модуль ЗУПа на эту библиотеку.
Думаю такие заявления сразу отпадут
облегчение повседневной разработки в 1С
kirillkr; +1 Ответить
7. user703054_vadja72 1 24.05.25 17:52 Сейчас в теме
(6) согласен с Вами, сложные запросы не переписать... ориентировано на начинающих программистов, на начальное обучение программированию.
и не на такие масштабные задачи, скорее как дополнение к имеющейся библиотеке и разработкам.
Для отправки сообщения требуется регистрация/авторизация