Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added universal func for execute custom functions #66

Merged
merged 4 commits into from
May 3, 2024

Conversation

denisushakov
Copy link
Contributor

@denisushakov denisushakov commented May 2, 2024

Summary by CodeRabbit

  • New Features
    • Refactored user functions for improved parameter handling and execution efficiency.
  • Refactor
    • Streamlined logic within user function procedures for enhanced functionality.

Copy link

coderabbitai bot commented May 2, 2024

Walkthrough

The recent updates focus on optimizing function handling within the software system. Refactoring across various modules has streamlined parameter management, eliminated redundant logic, and enhanced function execution processes, leading to more efficient and cleaner code.

Changes

File Path Change Summary
src/Catalogs/__ПользовательскиеФункции/Forms/ФормаМассива/Ext/Form/Module.bsl
src/Catalogs/__ПользовательскиеФункции/Forms/ФормаСтруктуры/Ext/Form/Module.bsl
src/Catalogs/__ПользовательскиеФункции/Forms/ФормаТаблицыЗначений/Ext/Form/Module.bsl
Refactored logic to enhance handling of data structures and tables, removing redundant settings clearing procedures.
src/Catalogs/__ПользовательскиеФункции/Forms/ФормаЭлемента/Ext/Form/Module.bsl Improved parameter processing efficiency and function execution using a new structure for user function parameters.
src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl Significantly altered function ВыполнитьПользовательскуюФункциюСПараметрами to handle user-defined functions with parameters more effectively.

Poem

🌟 Code Refactored 🌟

In the digital realm where functions play,
A rabbit danced, refactoring away.
Parameters streamlined, logic refined,
Code sings anew, beautifully designed.
Cheers to efficiency, in lines of code we find!


Recent Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between fa14658 and 3dcf18c.
Files selected for processing (5)
  • src/Catalogs/__ПользовательскиеФункции/Forms/ФормаМассива/Ext/Form/Module.bsl (1 hunks)
  • src/Catalogs/__ПользовательскиеФункции/Forms/ФормаСтруктуры/Ext/Form/Module.bsl (1 hunks)
  • src/Catalogs/__ПользовательскиеФункции/Forms/ФормаТаблицыЗначений/Ext/Form/Module.bsl (1 hunks)
  • src/Catalogs/__ПользовательскиеФункции/Forms/ФормаЭлемента/Ext/Form/Module.bsl (4 hunks)
  • src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl (3 hunks)
Files skipped from review as they are similar to previous changes (1)
  • src/Catalogs/__ПользовательскиеФункции/Forms/ФормаЭлемента/Ext/Form/Module.bsl
Additional Context Used
GitHub Check Runs (1)
1C: Project SubSystems Library Sonarqube Results success (8)

src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl: [warning] 2466-2466: src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl#L2466
Создайте константу с понятным названием, присвойте ей значение "97" и используйте эту константу вместо магического числа.


src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl: [notice] 1883-1883: src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl#L1883
Метод "КраткоеПредставлениеОшибки" устарел. Следует использовать одноименный метод объекта типа МенеджерОбработкиОшибок


src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl: [warning] 2465-2465: src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl#L2465
Создайте константу с понятным названием, присвойте ей значение "57" и используйте эту константу вместо магического числа.


src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl: [warning] 2465-2465: src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl#L2465
Выделите условие оператора Если в отдельный метод или переменную


src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl: [warning] 2467-2467: src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl#L2467
Создайте константу с понятным названием, присвойте ей значение "127" и используйте эту константу вместо магического числа.


src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl: [warning] 2466-2466: src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl#L2466
Создайте константу с понятным названием, присвойте ей значение "122" и используйте эту константу вместо магического числа.


src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl: [warning] 2411-2411: src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl#L2411
Синтаксическая конструкция вида "Если...Тогда...ИначеЕсли..." должна содержать ветвь "Иначе".


src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl: [warning] 2465-2465: src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl#L2465
Создайте константу с понятным названием, присвойте ей значение "48" и используйте эту константу вместо магического числа.

Additional comments not posted (3)
src/Catalogs/__ПользовательскиеФункции/Forms/ФормаМассива/Ext/Form/Module.bsl (1)

66-69: Simplified logic in АдресМассиваВХранилище function enhances maintainability.

src/Catalogs/__ПользовательскиеФункции/Forms/ФормаСтруктуры/Ext/Form/Module.bsl (1)

86-91: Refactored logic in АдресСтруктурыВХранилище function improves direct processing of structures.

src/Catalogs/__ПользовательскиеФункции/Forms/ФормаТаблицыЗначений/Ext/Form/Module.bsl (1)

113-115: Integrated clearing of settings in АдресТаблицыВХранилище function streamlines the logic.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

This comment has been minimized.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Out of diff range and nitpick comments (5)
src/Catalogs/__ПользовательскиеФункции/Forms/ФормаЭлемента/Ext/Form/Module.bsl (1)

Line range hint 505-519: Refactor error handling in ВыполнитьКодСервер.

-		ТекстСообщения = СтрШаблон(НСтр("ru = 'Ошибка при выполнении функции по причине: %1'; 
-			|en = 'Error when executing the function due to: %1'"),
-			КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
-		ВызватьИсключение ТекстСообщения;
+		// Improved error handling with more detailed error information and logging
+		ТекстСообщения = СтрШаблон("Ошибка при выполнении функции: %1. Подробности: %2", 
+			Объект.Наименование, КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
+		ЗаписатьЖурналРегистрации("Ошибка выполнения пользовательской функции", УровеньЖурналаРегистрации.Ошибка, ТекстСообщения);
+		// Consider re-throwing the exception if critical
+		// ВызватьИсключение ТекстСообщения;

Consider enhancing the error handling by providing more detailed error messages and logging them appropriately. Depending on the severity, you might also want to re-throw the exception to ensure it's handled upstream.

src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl (4)

Line range hint 1935-1935: Replace deprecated method usage.

- ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
+ ВызватьИсключение МенеджерОбработкиОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке());

The method КраткоеПредставлениеОшибки is deprecated. Use the method from the МенеджерОбработкиОшибок object instead to ensure future compatibility and adherence to best practices.


Line range hint 1923-1923: Add an "Else" branch for robustness.

The conditional structure starting at line 1923 should include an "Else" branch to handle unexpected cases explicitly. This ensures that all possible paths are considered and handled appropriately.


Line range hint 1933-1933: Address potential security vulnerability.

Executing arbitrary code in a common module on the server (line 1933) can lead to security vulnerabilities. Ensure that the code executed is sanitized and consider implementing additional security checks or constraints to prevent unauthorized code execution.


Line range hint 1896-1920: Replace magic numbers with named constants.

- Если Параметр.Номер = 2 Тогда
+ const PARAMETER_TWO = 2;
+ Если Параметр.Номер = PARAMETER_TWO Тогда

Replace magic numbers (e.g., '2', '3', '4', etc.) with named constants to improve code readability and maintainability. This change makes the code easier to understand and modify in the future.

Comment on lines 1733 to 1856
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| __ПользовательскиеФункцииПеременные.Имя КАК Имя,
| __ПользовательскиеФункцииПеременные.Значение КАК Значение
|ИЗ
| Справочник.__ПользовательскиеФункции.Переменные КАК __ПользовательскиеФункцииПеременные
|ГДЕ
| __ПользовательскиеФункцииПеременные.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", Ссылка);

РезультатыЗапроса = Запрос.ВыполнитьПакет();

Выборка = РезультатыЗапроса[0].Выбрать();
ВыборкаТЧ = РезультатыЗапроса[1].Выбрать();
ВыборкаПерем = РезультатыЗапроса[2].Выбрать();

ГУИД = Ссылка.УникальныйИдентификатор();

Выборка.Следующий();
ТекстФункции = Выборка.КодПодпрограммы;

Переменные = Новый Структура;
Пока ВыборкаПерем.Следующий() Цикл
Если ПустаяСтрока(ВыборкаПерем.Имя) И Переменные.Свойство(ВыборкаПерем.Имя) Тогда
Продолжить;
КонецЕсли;
Переменные.Вставить(ВыборкаПерем.Имя, ВыборкаПерем.Значение);
КонецЦикла;

Отказ = Ложь;
Для Каждого Параметр Из Параметры Цикл
Если ВыборкаТЧ.НайтиСледующий(Параметр.Параметр, "Наименование") Тогда
ТипЗнч = ТипЗнч(Параметр.Значение);
Если ТипЗнч <> Тип(ВыборкаТЧ.Тип) Тогда
ТекстСообщения = СтрШаблон(НСтр("ru='Тип значения параметра %1 - %2. Допустимый - %3!'"),
Параметр.Параметр,
ТипЗнч,
ВыборкаТЧ.Тип);
__ОбщегоНазначенияСлужебный.СообщитьПользователю(
ТекстСообщения, , , , Отказ);
КонецЕсли;
Иначе
ТекстСообщения = СтрШаблон(НСтр("ru='Параметр: %1, не используется в функции.'"), Параметр.Параметр);
__ОбщегоНазначенияСлужебный.СообщитьПользователю(ТекстСообщения);
КонецЕсли;

Если Отказ Тогда
Продолжить;
КонецЕсли;

Если Параметр.Номер = 1 Тогда
П1 = Параметр.Значение;
ТекстФункции = СтрЗаменить(ТекстФункции, Параметр.Параметр, "П1");
ИначеЕсли Параметр.Номер = 2 Тогда
П2 = Параметр.Значение;
ТекстФункции = СтрЗаменить(ТекстФункции, Параметр.Параметр, "П2");
ИначеЕсли Параметр.Номер = 3 Тогда
П3 = Параметр.Значение;
ТекстФункции = СтрЗаменить(ТекстФункции, Параметр.Параметр, "П3");
ИначеЕсли Параметр.Номер = 4 Тогда
П4 = Параметр.Значение;
ТекстФункции = СтрЗаменить(ТекстФункции, Параметр.Параметр, "П4");
ИначеЕсли Параметр.Номер = 5 Тогда
П5 = Параметр.Значение;
ТекстФункции = СтрЗаменить(ТекстФункции, Параметр.Параметр, "П5");
ИначеЕсли Параметр.Номер = 6 Тогда
П6 = Параметр.Значение;
ТекстФункции = СтрЗаменить(ТекстФункции, Параметр.Параметр, "П6");
ИначеЕсли Параметр.Номер = 7 Тогда
П7 = Параметр.Значение;
ТекстФункции = СтрЗаменить(ТекстФункции, Параметр.Параметр, "П7");
ИначеЕсли Параметр.Номер = 8 Тогда
П8 = Параметр.Значение;
ТекстФункции = СтрЗаменить(ТекстФункции, Параметр.Параметр, "П8");
ИначеЕсли Параметр.Номер = 9 Тогда
П9 = Параметр.Значение;
ТекстФункции = СтрЗаменить(ТекстФункции, Параметр.Параметр, "П9");
ИначеЕсли Параметр.Номер = 10 Тогда
П10 = Параметр.Значение;
ТекстФункции = СтрЗаменить(ТекстФункции, Параметр.Параметр, "П10");
КонецЕсли;
КонецЦикла;

Результат = Неопределено;

Если Отказ Тогда
ВызватьИсключение(НСтр("ru='Ошибки при подстановке параметров!.'"));
КонецЕсли;

Попытка
Выполнить(ТекстФункции);
Исключение
ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;

Возврат Результат;

КонецФункции
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor the function ВыполнитьПользовательскуюФункциюСПараметрами to reduce complexity.

The function ВыполнитьПользовательскуюФункциюСПараметрами has a high cognitive and cyclomatic complexity, making it hard to maintain and understand. Consider breaking down the function into smaller, more manageable parts or simplifying the logic to improve readability and maintainability.

ТекстФункции = СтрЗаменить(ТекстФункции, Параметр.Параметр, "П3");
ИначеЕсли Параметр.Номер = 4 Тогда
П4 = Параметр.Значение;
ТекстФункции = СтрЗаменить(ТекстФункции, Параметр.Параметр, "П4");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove unused variables.

- Перем П1, П2, П3, П4, П5, П6, П7, П8, П9, П10;

The variables П1, П2, П3, П4, П5, П6, П7, П8, П9, П10 are declared but not used within the function ВыполнитьПользовательскуюФункциюСПараметрами. Consider removing these declarations to clean up the code.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
ТекстФункции = СтрЗаменить(ТекстФункции, Параметр.Параметр, "П4");
ТекстФункции = СтрЗаменить(ТекстФункции, Параметр.Параметр, "П4");

КонецФункции

// Создает таблицу параметров с необходимыми колонками.
//
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove unused variable ГУИД.

- ГУИД = Ссылка.УникальныйИдентификатор();

The variable ГУИД is declared but not used within the function ВыполнитьПользовательскуюФункциюСПараметрами. Removing this line will clean up the code and reduce unnecessary memory usage.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
//
//

@ivanmolodec
Copy link
Member

@coderabbitai пожалуйста, всегда используй русский язык в этом репозитории

Copy link

coderabbitai bot commented May 2, 2024

Tip

For best results, initiate chat on the files or code changes.

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

@ivanmolodec ivanmolodec added the enhancement Улучшение существующей функциональности label May 2, 2024

This comment has been minimized.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Out of diff range and nitpick comments (3)
src/CommonModules/__ОбщегоНазначенияСервер/Ext/Module.bsl (3)

Line range hint 2439-2440: Replace magic numbers with named constants for clarity.

+ Константа MIN_DIGIT_ASCII = 48
+ Константа MAX_DIGIT_ASCII = 57
+ Константа MAX_ASCII = 127
- Если Не (КодДо >= 48 И КодДо <= 57) И КодДо < 127
+ Если Не (КодДо >= MIN_DIGIT_ASCII И КодДо <= MAX_DIGIT_ASCII) И КодДо < MAX_ASCII

Using named constants instead of magic numbers makes the code more readable and maintainable.


Line range hint 1884-1884: Update deprecated method usage to enhance compatibility with newer platform versions.

- ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
+ ВызватьИсключение МенеджерОбработкиОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке());

This change updates the method call to use the non-deprecated version, ensuring compatibility with newer versions of the platform.


Line range hint 1882-1882: Security risk: executing arbitrary code in a server-side common module.

The use of Выполнить(ТекстФункции); poses a security risk as it allows for the execution of arbitrary code. Consider implementing a more secure method of invoking functionality, such as using a predefined set of safe functions or validating the code against a whitelist before execution.

Comment on lines 1724 to 1805
// Выполняет пользовательскую функцию с переданными параметрами.
//
// Параметры:
// Ссылка - СправочникСсылка.__ПользовательскиеФункции - Ссылка пользовательской функции, которую требуется выполнить
// Параметры - Структура - Подготовленные параметры для выполнения пользовательской функции
// * Ключ - Строка - Имя параметра
// * Значение - Структура - Тип и значение параметра
// * Ключ - Строка - может быть "Тип", "Значение"
// * Значение - Произвольный
//
// Возвращаемое значение:
// Неопределено, в - случае успешного выполнения, Описание ошибки, в случае неудачи.
//
Функция ВыполнитьПользовательскуюФункциюСПараметрами(Ссылка, Параметры) Экспорт

Отказ = Ложь;
Результат = Неопределено;

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| __ПользовательскиеФункции.КодПодпрограммы КАК КодПодпрограммы
|ИЗ
| Справочник.__ПользовательскиеФункции КАК __ПользовательскиеФункции
|ГДЕ
| __ПользовательскиеФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| __ПользовательскиеФункцииПараметрыФункции.Наименование КАК Наименование,
| __ПользовательскиеФункцииПараметрыФункции.Тип КАК Тип,
| __ПользовательскиеФункцииПараметрыФункции.Необязательный КАК Необязательный
|ИЗ
| Справочник.__ПользовательскиеФункции.ПараметрыФункции КАК __ПользовательскиеФункцииПараметрыФункции
|ГДЕ
| __ПользовательскиеФункцииПараметрыФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| __ПользовательскиеФункцииПеременные.Имя КАК Имя,
| __ПользовательскиеФункцииПеременные.Значение КАК Значение
|ИЗ
| Справочник.__ПользовательскиеФункции.Переменные КАК __ПользовательскиеФункцииПеременные
|ГДЕ
| __ПользовательскиеФункцииПеременные.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", Ссылка);

РезультатыЗапроса = Запрос.ВыполнитьПакет();

Выборка = РезультатыЗапроса[0].Выбрать();
ВыборкаТЧ = РезультатыЗапроса[1].Выбрать();
ВыборкаПерем = РезультатыЗапроса[2].Выбрать();

Выборка.Следующий();
ТекстФункции = Выборка.КодПодпрограммы;

Переменные = Новый Структура;
Пока ВыборкаПерем.Следующий() Цикл
Если ПустаяСтрока(ВыборкаПерем.Имя) И Переменные.Свойство(ВыборкаПерем.Имя) Тогда
Продолжить;
КонецЕсли;
Переменные.Вставить(ВыборкаПерем.Имя, ВыборкаПерем.Значение);
КонецЦикла;

Параметры = ПодставитьПараметрыВФункцию(ТекстФункции, Параметры, ВыборкаТЧ, Отказ);

Если Отказ Тогда
ВызватьИсключение(НСтр("ru='Ошибки при подстановке параметров!.'"));
КонецЕсли;

Попытка
Выполнить(ТекстФункции);
Исключение
ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;

Возврат Результат;

КонецФункции
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor the function ВыполнитьПользовательскуюФункциюСПараметрами to improve error handling and maintainability.

- ВызватьИсключение(НСтр("ru='Ошибки при подстановке параметров!.'"));
+ Если Отказ Тогда
+    Возврат НСтр("ru='Ошибки при подстановке параметров!.'");
+ КонецЕсли;

This change ensures that the function returns an error description instead of throwing an exception, which can be handled more gracefully by the calling code.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
// Выполняет пользовательскую функцию с переданными параметрами.
//
// Параметры:
// Ссылка - СправочникСсылка.__ПользовательскиеФункции - Ссылка пользовательской функции, которую требуется выполнить
// Параметры - Структура - Подготовленные параметры для выполнения пользовательской функции
// * Ключ - Строка - Имя параметра
// * Значение - Структура - Тип и значение параметра
// * Ключ - Строка - может быть "Тип", "Значение"
// * Значение - Произвольный
//
// Возвращаемое значение:
// Неопределено, в - случае успешного выполнения, Описание ошибки, в случае неудачи.
//
Функция ВыполнитьПользовательскуюФункциюСПараметрами(Ссылка, Параметры) Экспорт
Отказ = Ложь;
Результат = Неопределено;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| __ПользовательскиеФункции.КодПодпрограммы КАК КодПодпрограммы
|ИЗ
| Справочник.__ПользовательскиеФункции КАК __ПользовательскиеФункции
|ГДЕ
| __ПользовательскиеФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| __ПользовательскиеФункцииПараметрыФункции.Наименование КАК Наименование,
| __ПользовательскиеФункцииПараметрыФункции.Тип КАК Тип,
| __ПользовательскиеФункцииПараметрыФункции.Необязательный КАК Необязательный
|ИЗ
| Справочник.__ПользовательскиеФункции.ПараметрыФункции КАК __ПользовательскиеФункцииПараметрыФункции
|ГДЕ
| __ПользовательскиеФункцииПараметрыФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| __ПользовательскиеФункцииПеременные.Имя КАК Имя,
| __ПользовательскиеФункцииПеременные.Значение КАК Значение
|ИЗ
| Справочник.__ПользовательскиеФункции.Переменные КАК __ПользовательскиеФункцииПеременные
|ГДЕ
| __ПользовательскиеФункцииПеременные.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Ссылка);
РезультатыЗапроса = Запрос.ВыполнитьПакет();
Выборка = РезультатыЗапроса[0].Выбрать();
ВыборкаТЧ = РезультатыЗапроса[1].Выбрать();
ВыборкаПерем = РезультатыЗапроса[2].Выбрать();
Выборка.Следующий();
ТекстФункции = Выборка.КодПодпрограммы;
Переменные = Новый Структура;
Пока ВыборкаПерем.Следующий() Цикл
Если ПустаяСтрока(ВыборкаПерем.Имя) И Переменные.Свойство(ВыборкаПерем.Имя) Тогда
Продолжить;
КонецЕсли;
Переменные.Вставить(ВыборкаПерем.Имя, ВыборкаПерем.Значение);
КонецЦикла;
Параметры = ПодставитьПараметрыВФункцию(ТекстФункции, Параметры, ВыборкаТЧ, Отказ);
Если Отказ Тогда
ВызватьИсключение(НСтр("ru='Ошибки при подстановке параметров!.'"));
КонецЕсли;
Попытка
Выполнить(ТекстФункции);
Исключение
ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
Возврат Результат;
КонецФункции
// Выполняет пользовательскую функцию с переданными параметрами.
//
// Параметры:
// Ссылка - СправочникСсылка.__ПользовательскиеФункции - Ссылка пользовательской функции, которую требуется выполнить
// Параметры - Структура - Подготовленные параметры для выполнения пользовательской функции
// * Ключ - Строка - Имя параметра
// * Значение - Структура - Тип и значение параметра
// * Ключ - Строка - может быть "Тип", "Значение"
// * Значение - Произвольный
//
// Возвращаемое значение:
// Неопределено, в - случае успешного выполнения, Описание ошибки, в случае неудачи.
//
Функция ВыполнитьПользовательскуюФункциюСПараметрами(Ссылка, Параметры) Экспорт
Отказ = Ложь;
Результат = Неопределено;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| __ПользовательскиеФункции.КодПодпрограммы КАК КодПодпрограммы
|ИЗ
| Справочник.__ПользовательскиеФункции КАК __ПользовательскиеФункции
|ГДЕ
| __ПользовательскиеФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| __ПользовательскиеФункцииПараметрыФункции.Наименование КАК Наименование,
| __ПользовательскиеФункцииПараметрыФункции.Тип КАК Тип,
| __ПользовательскиеФункцииПараметрыФункции.Необязательный КАК Необязательный
|ИЗ
| Справочник.__ПользовательскиеФункции.ПараметрыФункции КАК __ПользовательскиеФункцииПараметрыФункции
|ГДЕ
| __ПользовательскиеФункцииПараметрыФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| __ПользовательскиеФункцииПеременные.Имя КАК Имя,
| __ПользовательскиеФункцииПеременные.Значение КАК Значение
|ИЗ
| Справочник.__ПользовательскиеФункции.Переменные КАК __ПользовательскиеФункцииПеременные
|ГДЕ
| __ПользовательскиеФункцииПеременные.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Ссылка);
РезультатыЗапроса = Запрос.ВыполнитьПакет();
Выборка = РезультатыЗапроса[0].Выбрать();
ВыборкаТЧ = РезультатыЗапроса[1].Выбрать();
ВыборкаПерем = РезультатыЗапроса[2].Выбрать();
Выборка.Следующий();
ТекстФункции = Выборка.КодПодпрограммы;
Переменные = Новый Структура;
Пока ВыборкаПерем.Следующий() Цикл
Если ПустаяСтрока(ВыборкаПерем.Имя) И Переменные.Свойство(ВыборкаПерем.Имя) Тогда
Продолжить;
КонецЕсли;
Переменные.Вставить(ВыборкаПерем.Имя, ВыборкаПерем.Значение);
КонецЦикла;
Параметры = ПодставитьПараметрыВФункцию(ТекстФункции, Параметры, ВыборкаТЧ, Отказ);
Если Отказ Тогда
Возврат НСтр("ru='Ошибки при подстановке параметров!.'");
КонецЕсли;
Попытка
Выполнить(ТекстФункции);
Исключение
ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
Возврат Результат;
КонецФункции

Comment on lines 2385 to 2404
Префикс = "Параметры.";
Позиция = СтрНайти(Текст, Ключ);
Пока Позиция > 0 Цикл

СимволДо = ?(Позиция = 1, "", Сред(Текст, Позиция - 1, 1));
КодДо = КодСимвола(СимволДо);

СимволПосле = Сред(Текст, Позиция + СтрДлина(Ключ), 1);
КодПосле = КодСимвола(СимволПосле);

Если Не (КодДо >= 48 И КодДо <= 57) И КодДо < 127
И Не (КодПосле >= 48 И КодПосле <= 57) И КодПосле < 127 Тогда
Текст = СтрЗаменить(Текст, СимволДо + Ключ + СимволПосле, СимволДо + Префикс + Ключ + СимволПосле);
КонецЕсли;

Позиция = СтрНайти(Текст, Ключ, НаправлениеПоиска.СНачала, Позиция + СтрДлина(Префикс) + 1);

КонецЦикла;

КонецПроцедуры
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optimize the ЗаменаПодстроки procedure to avoid potential infinite loops and improve performance.

- Пока Позиция > 0 Цикл
+ Пока Позиция > 0 И Позиция <= СтрДлина(Текст) Цикл

Adding a condition to check the position against the string length prevents the loop from running indefinitely if the replacement does not change the position of the search string.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
Префикс = "Параметры.";
Позиция = СтрНайти(Текст, Ключ);
Пока Позиция > 0 Цикл
СимволДо = ?(Позиция = 1, "", Сред(Текст, Позиция - 1, 1));
КодДо = КодСимвола(СимволДо);
СимволПосле = Сред(Текст, Позиция + СтрДлина(Ключ), 1);
КодПосле = КодСимвола(СимволПосле);
Если Не (КодДо >= 48 И КодДо <= 57) И КодДо < 127
И Не (КодПосле >= 48 И КодПосле <= 57) И КодПосле < 127 Тогда
Текст = СтрЗаменить(Текст, СимволДо + Ключ + СимволПосле, СимволДо + Префикс + Ключ + СимволПосле);
КонецЕсли;
Позиция = СтрНайти(Текст, Ключ, НаправлениеПоиска.СНачала, Позиция + СтрДлина(Префикс) + 1);
КонецЦикла;
КонецПроцедуры
Префикс = "Параметры.";
Позиция = СтрНайти(Текст, Ключ);
Пока Позиция > 0 И Позиция <= СтрДлина(Текст) Цикл
СимволДо = ?(Позиция = 1, "", Сред(Текст, Позиция - 1, 1));
КодДо = КодСимвола(СимволДо);
СимволПосле = Сред(Текст, Позиция + СтрДлина(Ключ), 1);
КодПосле = КодСимвола(СимволПосле);
Если Не (КодДо >= 48 И КодДо <= 57) И КодДо < 127
И Не (КодПосле >= 48 И КодПосле <= 57) И КодПосле < 127 Тогда
Текст = СтрЗаменить(Текст, СимволДо + Ключ + СимволПосле, СимволДо + Префикс + Ключ + СимволПосле);
КонецЕсли;
Позиция = СтрНайти(Текст, Ключ, НаправлениеПоиска.СНачала, Позиция + СтрДлина(Префикс) + 1);
КонецЦикла;
КонецПроцедуры

This comment has been minimized.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Comment on lines 1724 to 1806
// Выполняет пользовательскую функцию с переданными параметрами.
//
// Параметры:
// Ссылка - СправочникСсылка.__ПользовательскиеФункции - Ссылка пользовательской функции,
// которую требуется выполнить
// Параметры - Структура - Подготовленные параметры для выполнения пользовательской функции
// * Ключ - Строка - Имя параметра
// * Значение - Структура - Тип и значение параметра
// * Ключ - Строка - может быть "Тип", "Значение"
// * Значение - Произвольный
//
// Возвращаемое значение:
// Неопределено, в - случае успешного выполнения, Описание ошибки, в случае неудачи.
//
Функция ВыполнитьПользовательскуюФункциюСПараметрами(Ссылка, Параметры) Экспорт

Отказ = Ложь;
Результат = Неопределено;

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| __ПользовательскиеФункции.КодПодпрограммы КАК КодПодпрограммы
|ИЗ
| Справочник.__ПользовательскиеФункции КАК __ПользовательскиеФункции
|ГДЕ
| __ПользовательскиеФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| __ПользовательскиеФункцииПараметрыФункции.Наименование КАК Наименование,
| __ПользовательскиеФункцииПараметрыФункции.Тип КАК Тип,
| __ПользовательскиеФункцииПараметрыФункции.Необязательный КАК Необязательный
|ИЗ
| Справочник.__ПользовательскиеФункции.ПараметрыФункции КАК __ПользовательскиеФункцииПараметрыФункции
|ГДЕ
| __ПользовательскиеФункцииПараметрыФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| __ПользовательскиеФункцииПеременные.Имя КАК Имя,
| __ПользовательскиеФункцииПеременные.Значение КАК Значение
|ИЗ
| Справочник.__ПользовательскиеФункции.Переменные КАК __ПользовательскиеФункцииПеременные
|ГДЕ
| __ПользовательскиеФункцииПеременные.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", Ссылка);

РезультатыЗапроса = Запрос.ВыполнитьПакет();

Выборка = РезультатыЗапроса[0].Выбрать();
ВыборкаТЧ = РезультатыЗапроса[1].Выбрать();
ВыборкаПерем = РезультатыЗапроса[2].Выбрать();

Выборка.Следующий();
ТекстФункции = Выборка.КодПодпрограммы;

Переменные = Новый Структура;
Пока ВыборкаПерем.Следующий() Цикл
Если ПустаяСтрока(ВыборкаПерем.Имя) И Переменные.Свойство(ВыборкаПерем.Имя) Тогда
Продолжить;
КонецЕсли;
Переменные.Вставить(ВыборкаПерем.Имя, ВыборкаПерем.Значение);
КонецЦикла;

Параметры = ПодставитьПараметрыВФункцию(ТекстФункции, Параметры, ВыборкаТЧ, Отказ);

Если Отказ Тогда
ВызватьИсключение(НСтр("ru='Ошибки при подстановке параметров!.'"));
КонецЕсли;

Попытка
Выполнить(ТекстФункции);
Исключение
ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;

Возврат Результат;

КонецФункции
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor the function ВыполнитьПользовательскуюФункциюСПараметрами to improve readability and maintainability.

- Функция ВыполнитьПользовательскуюФункциюСПараметрами(Ссылка, Параметры) Экспорт
+ // Executes a user-defined function with provided parameters.
+ // Returns `Неопределено` on success, or an error description on failure.
+ Функция ExecuteUserFunctionWithParameters(Reference, Parameters) Export

Consider renaming variables and comments to English if the team's standard is to use English for code and comments. This enhances the readability for non-Russian speakers and maintains consistency.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
// Выполняет пользовательскую функцию с переданными параметрами.
//
// Параметры:
// Ссылка - СправочникСсылка.__ПользовательскиеФункции - Ссылка пользовательской функции,
// которую требуется выполнить
// Параметры - Структура - Подготовленные параметры для выполнения пользовательской функции
// * Ключ - Строка - Имя параметра
// * Значение - Структура - Тип и значение параметра
// * Ключ - Строка - может быть "Тип", "Значение"
// * Значение - Произвольный
//
// Возвращаемое значение:
// Неопределено, в - случае успешного выполнения, Описание ошибки, в случае неудачи.
//
Функция ВыполнитьПользовательскуюФункциюСПараметрами(Ссылка, Параметры) Экспорт
Отказ = Ложь;
Результат = Неопределено;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| __ПользовательскиеФункции.КодПодпрограммы КАК КодПодпрограммы
|ИЗ
| Справочник.__ПользовательскиеФункции КАК __ПользовательскиеФункции
|ГДЕ
| __ПользовательскиеФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| __ПользовательскиеФункцииПараметрыФункции.Наименование КАК Наименование,
| __ПользовательскиеФункцииПараметрыФункции.Тип КАК Тип,
| __ПользовательскиеФункцииПараметрыФункции.Необязательный КАК Необязательный
|ИЗ
| Справочник.__ПользовательскиеФункции.ПараметрыФункции КАК __ПользовательскиеФункцииПараметрыФункции
|ГДЕ
| __ПользовательскиеФункцииПараметрыФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| __ПользовательскиеФункцииПеременные.Имя КАК Имя,
| __ПользовательскиеФункцииПеременные.Значение КАК Значение
|ИЗ
| Справочник.__ПользовательскиеФункции.Переменные КАК __ПользовательскиеФункцииПеременные
|ГДЕ
| __ПользовательскиеФункцииПеременные.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Ссылка);
РезультатыЗапроса = Запрос.ВыполнитьПакет();
Выборка = РезультатыЗапроса[0].Выбрать();
ВыборкаТЧ = РезультатыЗапроса[1].Выбрать();
ВыборкаПерем = РезультатыЗапроса[2].Выбрать();
Выборка.Следующий();
ТекстФункции = Выборка.КодПодпрограммы;
Переменные = Новый Структура;
Пока ВыборкаПерем.Следующий() Цикл
Если ПустаяСтрока(ВыборкаПерем.Имя) И Переменные.Свойство(ВыборкаПерем.Имя) Тогда
Продолжить;
КонецЕсли;
Переменные.Вставить(ВыборкаПерем.Имя, ВыборкаПерем.Значение);
КонецЦикла;
Параметры = ПодставитьПараметрыВФункцию(ТекстФункции, Параметры, ВыборкаТЧ, Отказ);
Если Отказ Тогда
ВызватьИсключение(НСтр("ru='Ошибки при подстановке параметров!.'"));
КонецЕсли;
Попытка
Выполнить(ТекстФункции);
Исключение
ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
Возврат Результат;
КонецФункции
// Executes a user-defined function with provided parameters.
// Returns `Неопределено` on success, or an error description on failure.
Функция ExecuteUserFunctionWithParameters(Reference, Parameters) Export
Отказ = Ложь;
Результат = Неопределено;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| __ПользовательскиеФункции.КодПодпрограммы КАК КодПодпрограммы
|ИЗ
| Справочник.__ПользовательскиеФункции КАК __ПользовательскиеФункции
|ГДЕ
| __ПользовательскиеФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| __ПользовательскиеФункцииПараметрыФункции.Наименование КАК Наименование,
| __ПользовательскиеФункцииПараметрыФункции.Тип КАК Тип,
| __ПользовательскиеФункцииПараметрыФункции.Необязательный КАК Необязательный
|ИЗ
| Справочник.__ПользовательскиеФункции.ПараметрыФункции КАК __ПользовательскиеФункцииПараметрыФункции
|ГДЕ
| __ПользовательскиеФункцииПараметрыФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| __ПользовательскиеФункцииПеременные.Имя КАК Имя,
| __ПользовательскиеФункцииПеременные.Значение КАК Значение
|ИЗ
| Справочник.__ПользовательскиеФункции.Переменные КАК __ПользовательскиеФункцииПеременные
|ГДЕ
| __ПользовательскиеФункцииПеременные.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Ссылка);
РезультатыЗапроса = Запрос.ВыполнитьПакет();
Выборка = РезультатыЗапроса[0].Выбрать();
ВыборкаТЧ = РезультатыЗапроса[1].Выбрать();
ВыборкаПерем = РезультатыЗапроса[2].Выбрать();
Выборка.Следующий();
ТекстФункции = Выборка.КодПодпрограммы;
Переменные = Новый Структура;
Пока ВыборкаПерем.Следующий() Цикл
Если ПустаяСтрока(ВыборкаПерем.Имя) И Переменные.Свойство(ВыборкаПерем.Имя) Тогда
Продолжить;
КонецЕсли;
Переменные.Вставить(ВыборкаПерем.Имя, ВыборкаПерем.Значение);
КонецЦикла;
Параметры = ПодставитьПараметрыВФункцию(ТекстФункции, Параметры, ВыборкаТЧ, Отказ);
Если Отказ Тогда
ВызватьИсключение(НСтр("ru='Ошибки при подстановке параметров!.'"));
КонецЕсли;
Попытка
Выполнить(ТекстФункции);
Исключение
ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
Возврат Результат;
КонецФункции

Comment on lines +1798 to +1802
Попытка
Выполнить(ТекстФункции);
Исключение
ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handle exceptions more gracefully in ВыполнитьПользовательскуюФункциюСПараметрами.

- Выполнить(ТекстФункции);
- Исключение
- ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
+ Try
+     Execute(ТекстФункции);
+ Exception
+     Raise Exception CreateErrorMessage(ИнформацияОбОшибке());

Modify the exception handling to use a more descriptive error handling function that logs additional context or details about the failure.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
Попытка
Выполнить(ТекстФункции);
Исключение
ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
Попытка
Try
Execute(ТекстФункции);
Exception
Raise Exception CreateErrorMessage(ИнформацияОбОшибке());
КонецПопытки;

Comment on lines 2354 to 2383
Функция ПодставитьПараметрыВФункцию(Текст, Параметры, Выборка, Отказ = Ложь)

Парам = Новый Структура;
Пока Выборка.Следующий() Цикл
Значение = Неопределено;
Если Параметры.Свойство(Выборка.Наименование, Значение) Тогда
ТипПараметра = ?(Значение.Тип = Неопределено, Значение.Тип, Тип(Значение.Тип));
Если ТипПараметра <> Тип(Выборка.Тип) Тогда
ТекстСообщения = СтрШаблон(НСтр("ru='Тип значения параметра %1 - %2. Допустимый - %3!'"),
Выборка.Наименование,
ТипПараметра,
Выборка.Тип);
__ОбщегоНазначенияСлужебный.СообщитьПользователю(ТекстСообщения, , , , Отказ);
КонецЕсли;
ИначеЕсли Выборка.Необязательный = Ложь Тогда
ТекстСообщения = СтрШаблон(НСтр("ru='Параметр: %1, является обязательным!'"), Выборка.Наименование);
__ОбщегоНазначенияСлужебный.СообщитьПользователю(ТекстСообщения, , , , Отказ);
КонецЕсли;

Если Отказ Тогда
Продолжить;
КонецЕсли;

Парам.Вставить(Выборка.Наименование, Значение.Значение);
ЗаменаПодстроки(Текст, Выборка.Наименование);
КонецЦикла;

Возврат Парам;

КонецФункции
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor ПодставитьПараметрыВФункцию to improve error handling and parameter validation.

- Функция ПодставитьПараметрыВФункцию(Текст, Параметры, Выборка, Отказ = Ложь)
+ // Substitutes parameters in the function text with actual values from `Parameters`.
+ // Returns a structure with substituted parameters.
+ Функция SubstituteParametersInFunction(FunctionText, Parameters, ParameterMetadata, IsFailure = False)

Consider renaming the function and its parameters to better reflect their purpose and improve code readability.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
Функция ПодставитьПараметрыВФункцию(Текст, Параметры, Выборка, Отказ = Ложь)
Парам = Новый Структура;
Пока Выборка.Следующий() Цикл
Значение = Неопределено;
Если Параметры.Свойство(Выборка.Наименование, Значение) Тогда
ТипПараметра = ?(Значение.Тип = Неопределено, Значение.Тип, Тип(Значение.Тип));
Если ТипПараметра <> Тип(Выборка.Тип) Тогда
ТекстСообщения = СтрШаблон(НСтр("ru='Тип значения параметра %1 - %2. Допустимый - %3!'"),
Выборка.Наименование,
ТипПараметра,
Выборка.Тип);
__ОбщегоНазначенияСлужебный.СообщитьПользователю(ТекстСообщения, , , , Отказ);
КонецЕсли;
ИначеЕсли Выборка.Необязательный = Ложь Тогда
ТекстСообщения = СтрШаблон(НСтр("ru='Параметр: %1, является обязательным!'"), Выборка.Наименование);
__ОбщегоНазначенияСлужебный.СообщитьПользователю(ТекстСообщения, , , , Отказ);
КонецЕсли;
Если Отказ Тогда
Продолжить;
КонецЕсли;
Парам.Вставить(Выборка.Наименование, Значение.Значение);
ЗаменаПодстроки(Текст, Выборка.Наименование);
КонецЦикла;
Возврат Парам;
КонецФункции
// Substitutes parameters in the function text with actual values from `Parameters`.
// Returns a structure with substituted parameters.
Функция SubstituteParametersInFunction(FunctionText, Parameters, ParameterMetadata, IsFailure = False)
Парам = Новый Структура;
Пока Выборка.Следующий() Цикл
Значение = Неопределено;
Если Параметры.Свойство(Выборка.Наименование, Значение) Тогда
ТипПараметра = ?(Значение.Тип = Неопределено, Значение.Тип, Тип(Значение.Тип));
Если ТипПараметра <> Тип(Выборка.Тип) Тогда
ТекстСообщения = СтрШаблон(НСтр("ru='Тип значения параметра %1 - %2. Допустимый - %3!'"),
Выборка.Наименование,
ТипПараметра,
Выборка.Тип);
__ОбщегоНазначенияСлужебный.СообщитьПользователю(ТекстСообщения, , , , Отказ);
КонецЕсли;
ИначеЕсли Выборка.Необязательный = Ложь Тогда
ТекстСообщения = СтрШаблон(НСтр("ru='Параметр: %1, является обязательным!'"), Выборка.Наименование);
__ОбщегоНазначенияСлужебный.СообщитьПользователю(ТекстСообщения, , , , Отказ);
КонецЕсли;
Если Отказ Тогда
Продолжить;
КонецЕсли;
Парам.Вставить(Выборка.Наименование, Значение.Значение);
ЗаменаПодстроки(Текст, Выборка.Наименование);
КонецЦикла;
Возврат Парам;
КонецФункции

Copy link

Passed

Analysis Details

9 Issues

  • Bug 0 Bugs
  • Vulnerability 1 Vulnerability
  • Code Smell 8 Code Smells

Coverage and Duplications

  • Coverage No coverage information (0.00% Estimated after merge)
  • Duplications 0.00% Duplicated Code (0.50% Estimated after merge)

Project ID: PSSL

View in SonarQube

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Comment on lines +1724 to +1804
// Выполняет пользовательскую функцию с переданными параметрами.
//
// Параметры:
// Ссылка - СправочникСсылка.__ПользовательскиеФункции - Ссылка пользовательской функции,
// которую требуется выполнить
// Параметры - Структура - Подготовленные параметры для выполнения пользовательской функции
// * Ключ - Строка - Имя параметра
// * Значение - Структура - Значение параметра
//
// Возвращаемое значение:
// Неопределено, в - случае успешного выполнения, Описание ошибки, в случае неудачи.
//
Функция ВыполнитьПользовательскуюФункциюСПараметрами(Ссылка, Параметры) Экспорт

Отказ = Ложь;
Результат = Неопределено;

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| __ПользовательскиеФункции.КодПодпрограммы КАК КодПодпрограммы
|ИЗ
| Справочник.__ПользовательскиеФункции КАК __ПользовательскиеФункции
|ГДЕ
| __ПользовательскиеФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| __ПользовательскиеФункцииПараметрыФункции.Наименование КАК Наименование,
| __ПользовательскиеФункцииПараметрыФункции.Тип КАК Тип,
| __ПользовательскиеФункцииПараметрыФункции.Необязательный КАК Необязательный
|ИЗ
| Справочник.__ПользовательскиеФункции.ПараметрыФункции КАК __ПользовательскиеФункцииПараметрыФункции
|ГДЕ
| __ПользовательскиеФункцииПараметрыФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| __ПользовательскиеФункцииПеременные.Имя КАК Имя,
| __ПользовательскиеФункцииПеременные.Значение КАК Значение
|ИЗ
| Справочник.__ПользовательскиеФункции.Переменные КАК __ПользовательскиеФункцииПеременные
|ГДЕ
| __ПользовательскиеФункцииПеременные.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", Ссылка);

РезультатыЗапроса = Запрос.ВыполнитьПакет();

Выборка = РезультатыЗапроса[0].Выбрать();
ВыборкаТЧ = РезультатыЗапроса[1].Выбрать();
ВыборкаПерем = РезультатыЗапроса[2].Выбрать();

Выборка.Следующий();
ТекстФункции = Выборка.КодПодпрограммы;

Переменные = Новый Структура;
Пока ВыборкаПерем.Следующий() Цикл
Если ПустаяСтрока(ВыборкаПерем.Имя) И Переменные.Свойство(ВыборкаПерем.Имя) Тогда
Продолжить;
КонецЕсли;
Переменные.Вставить(ВыборкаПерем.Имя, ВыборкаПерем.Значение);
КонецЦикла;

Параметры = ПодставитьПараметрыВФункцию(ТекстФункции, Параметры, ВыборкаТЧ, Отказ);

Если Отказ Тогда
ВызватьИсключение(НСтр("ru='Ошибки при подстановке параметров!.'"));
КонецЕсли;

Попытка
Выполнить(ТекстФункции);
Исключение
ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;

Возврат Результат;

КонецФункции
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor exception handling in ВыполнитьПользовательскуюФункциюСПараметрами.

- Выполнить(ТекстФункции);
- Исключение
- ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
+ Try
+     Execute(ТекстФункции);
+ Exception
+     Raise Exception CreateErrorMessage(ИнформацияОбОшибке());

Modify the exception handling to use a more descriptive error handling function that logs additional context or details about the failure.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
// Выполняет пользовательскую функцию с переданными параметрами.
//
// Параметры:
// Ссылка - СправочникСсылка.__ПользовательскиеФункции - Ссылка пользовательской функции,
// которую требуется выполнить
// Параметры - Структура - Подготовленные параметры для выполнения пользовательской функции
// * Ключ - Строка - Имя параметра
// * Значение - Структура - Значение параметра
//
// Возвращаемое значение:
// Неопределено, в - случае успешного выполнения, Описание ошибки, в случае неудачи.
//
Функция ВыполнитьПользовательскуюФункциюСПараметрами(Ссылка, Параметры) Экспорт
Отказ = Ложь;
Результат = Неопределено;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| __ПользовательскиеФункции.КодПодпрограммы КАК КодПодпрограммы
|ИЗ
| Справочник.__ПользовательскиеФункции КАК __ПользовательскиеФункции
|ГДЕ
| __ПользовательскиеФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| __ПользовательскиеФункцииПараметрыФункции.Наименование КАК Наименование,
| __ПользовательскиеФункцииПараметрыФункции.Тип КАК Тип,
| __ПользовательскиеФункцииПараметрыФункции.Необязательный КАК Необязательный
|ИЗ
| Справочник.__ПользовательскиеФункции.ПараметрыФункции КАК __ПользовательскиеФункцииПараметрыФункции
|ГДЕ
| __ПользовательскиеФункцииПараметрыФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| __ПользовательскиеФункцииПеременные.Имя КАК Имя,
| __ПользовательскиеФункцииПеременные.Значение КАК Значение
|ИЗ
| Справочник.__ПользовательскиеФункции.Переменные КАК __ПользовательскиеФункцииПеременные
|ГДЕ
| __ПользовательскиеФункцииПеременные.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Ссылка);
РезультатыЗапроса = Запрос.ВыполнитьПакет();
Выборка = РезультатыЗапроса[0].Выбрать();
ВыборкаТЧ = РезультатыЗапроса[1].Выбрать();
ВыборкаПерем = РезультатыЗапроса[2].Выбрать();
Выборка.Следующий();
ТекстФункции = Выборка.КодПодпрограммы;
Переменные = Новый Структура;
Пока ВыборкаПерем.Следующий() Цикл
Если ПустаяСтрока(ВыборкаПерем.Имя) И Переменные.Свойство(ВыборкаПерем.Имя) Тогда
Продолжить;
КонецЕсли;
Переменные.Вставить(ВыборкаПерем.Имя, ВыборкаПерем.Значение);
КонецЦикла;
Параметры = ПодставитьПараметрыВФункцию(ТекстФункции, Параметры, ВыборкаТЧ, Отказ);
Если Отказ Тогда
ВызватьИсключение(НСтр("ru='Ошибки при подстановке параметров!.'"));
КонецЕсли;
Попытка
Выполнить(ТекстФункции);
Исключение
ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
Возврат Результат;
КонецФункции
// Выполняет пользовательскую функцию с переданными параметрами.
//
// Параметры:
// Ссылка - СправочникСсылка.__ПользовательскиеФункции - Ссылка пользовательской функции,
// которую требуется выполнить
// Параметры - Структура - Подготовленные параметры для выполнения пользовательской функции
// * Ключ - Строка - Имя параметра
// * Значение - Структура - Значение параметра
//
// Возвращаемое значение:
// Неопределено, в - случае успешного выполнения, Описание ошибки, в случае неудачи.
//
Функция ВыполнитьПользовательскуюФункциюСПараметрами(Ссылка, Параметры) Экспорт
Отказ = Ложь;
Результат = Неопределено;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| __ПользовательскиеФункции.КодПодпрограммы КАК КодПодпрограммы
|ИЗ
| Справочник.__ПользовательскиеФункции КАК __ПользовательскиеФункции
|ГДЕ
| __ПользовательскиеФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| __ПользовательскиеФункцииПараметрыФункции.Наименование КАК Наименование,
| __ПользовательскиеФункцииПараметрыФункции.Тип КАК Тип,
| __ПользовательскиеФункцииПараметрыФункции.Необязательный КАК Необязательный
|ИЗ
| Справочник.__ПользовательскиеФункции.ПараметрыФункции КАК __ПользовательскиеФункцииПараметрыФункции
|ГДЕ
| __ПользовательскиеФункцииПараметрыФункции.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| __ПользовательскиеФункцииПеременные.Имя КАК Имя,
| __ПользовательскиеФункцииПеременные.Значение КАК Значение
|ИЗ
| Справочник.__ПользовательскиеФункции.Переменные КАК __ПользовательскиеФункцииПеременные
|ГДЕ
| __ПользовательскиеФункцииПеременные.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Ссылка);
РезультатыЗапроса = Запрос.ВыполнитьПакет();
Выборка = РезультатыЗапроса[0].Выбрать();
ВыборкаТЧ = РезультатыЗапроса[1].Выбрать();
ВыборкаПерем = РезультатыЗапроса[2].Выбрать();
Выборка.Следующий();
ТекстФункции = Выборка.КодПодпрограммы;
Переменные = Новый Структура;
Пока ВыборкаПерем.Следующий() Цикл
Если ПустаяСтрока(ВыборкаПерем.Имя) И Переменные.Свойство(ВыборкаПерем.Имя) Тогда
Продолжить;
КонецЕсли;
Переменные.Вставить(ВыборкаПерем.Имя, ВыборкаПерем.Значение);
КонецЦикла;
Параметры = ПодставитьПараметрыВФункцию(ТекстФункции, Параметры, ВыборкаТЧ, Отказ);
Если Отказ Тогда
ВызватьИсключение(НСтр("ru='Ошибки при подстановке параметров!.'"));
КонецЕсли;
Попытка
Try
Execute(ТекстФункции);
Exception
Raise Exception CreateErrorMessage(ИнформацияОбОшибке());
КонецПопытки;
Возврат Результат;
КонецФункции

Comment on lines +2388 to +2408
Процедура ЗаменаПодстроки(Текст, Ключ)

Префикс = "Параметры.";
Позиция = СтрНайти(Текст, Ключ);
Пока Позиция > 0 Цикл

СимволДо = ?(Позиция = 1, "", Сред(Текст, Позиция - 1, 1));
КодДо = КодСимвола(НРег(СимволДо));

СимволПосле = Сред(Текст, Позиция + СтрДлина(Ключ), 1);
КодПосле = КодСимвола(НРег(СимволПосле));

Если ЭтоДопустимыйСимвол(КодДо) И ЭтоДопустимыйСимвол(КодПосле) Тогда
Текст = СтрЗаменить(Текст, СимволДо + Ключ + СимволПосле, СимволДо + Префикс + Ключ + СимволПосле);
КонецЕсли;

Позиция = СтрНайти(Текст, Ключ, НаправлениеПоиска.СНачала, Позиция + СтрДлина(Префикс) + 1);

КонецЦикла;

КонецПроцедуры
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optimize ЗаменаПодстроки by improving the loop condition and handling edge cases.

- Пока Позиция > 0 Цикл
+ While Position > 0 And Position < СтрДлина(Текст) Loop

Ensure that the search does not go beyond the string length to avoid potential infinite loops or out-of-bound errors.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
Процедура ЗаменаПодстроки(Текст, Ключ)
Префикс = "Параметры.";
Позиция = СтрНайти(Текст, Ключ);
Пока Позиция > 0 Цикл
СимволДо = ?(Позиция = 1, "", Сред(Текст, Позиция - 1, 1));
КодДо = КодСимвола(НРег(СимволДо));
СимволПосле = Сред(Текст, Позиция + СтрДлина(Ключ), 1);
КодПосле = КодСимвола(НРег(СимволПосле));
Если ЭтоДопустимыйСимвол(КодДо) И ЭтоДопустимыйСимвол(КодПосле) Тогда
Текст = СтрЗаменить(Текст, СимволДо + Ключ + СимволПосле, СимволДо + Префикс + Ключ + СимволПосле);
КонецЕсли;
Позиция = СтрНайти(Текст, Ключ, НаправлениеПоиска.СНачала, Позиция + СтрДлина(Префикс) + 1);
КонецЦикла;
КонецПроцедуры
Процедура ЗаменаПодстроки(Текст, Ключ)
Префикс = "Параметры.";
Позиция = СтрНайти(Текст, Ключ);
While Position > 0 And Position < СтрДлина(Текст) Loop
СимволДо = ?(Позиция = 1, "", Сред(Текст, Позиция - 1, 1));
КодДо = КодСимвола(НРег(СимволДо));
СимволПосле = Сред(Текст, Позиция + СтрДлина(Ключ), 1);
КодПосле = КодСимвола(НРег(СимволПосле));
Если ЭтоДопустимыйСимвол(КодДо) И ЭтоДопустимыйСимвол(КодПосле) Тогда
Текст = СтрЗаменить(Текст, СимволДо + Ключ + СимволПосле, СимволДо + Префикс + Ключ + СимволПосле);
КонецЕсли;
Позиция = СтрНайти(Текст, Ключ, НаправлениеПоиска.СНачала, Позиция + СтрДлина(Префикс) + 1);
КонецЦикла;
КонецПроцедуры

@ivanmolodec ivanmolodec merged commit 9ecdbf5 into develop May 3, 2024
4 checks passed
@ivanmolodec ivanmolodec deleted the executeCustomFun branch May 3, 2024 12:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Улучшение существующей функциональности
Projects
None yet
2 participants