├── .settings └── org.eclipse.core.resources.prefs ├── DT-INF └── PROJECT.PMF ├── .gitignore ├── src ├── Subsystems │ └── KASL │ │ ├── KASL.mdo │ │ └── Subsystems │ │ └── АТДМассив │ │ └── АТДМассив.mdo ├── CommonModules │ ├── РаботаСКоллекцией │ │ ├── РаботаСКоллекцией.mdo │ │ └── Module.bsl │ ├── РаботаСМассивом │ │ ├── РаботаСМассивом.mdo │ │ └── Module.bsl │ ├── РаботаСОчередью │ │ ├── РаботаСОчередью.mdo │ │ └── Module.bsl │ └── РаботаСМножеством │ │ ├── РаботаСМножеством.mdo │ │ └── Module.bsl ├── DataProcessors │ └── АТДМассив │ │ ├── АТДМассив.mdo │ │ ├── Forms │ │ └── Форма │ │ │ ├── Form.form │ │ │ └── Module.bsl │ │ └── ObjectModule.bsl └── Configuration │ └── Configuration.mdo ├── .project ├── LICENSE └── README.md /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding/=UTF-8 3 | -------------------------------------------------------------------------------- /DT-INF/PROJECT.PMF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Runtime-Version: 8.3.25 3 | Base-Project: KASL-extentions 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IDE 2 | /.metadata/ 3 | /.settings/ 4 | /.obsidian/ 5 | 6 | # Binary 7 | bin 8 | InfoBases 9 | tools 10 | examples -------------------------------------------------------------------------------- /src/Subsystems/KASL/KASL.mdo: -------------------------------------------------------------------------------- 1 | 2 | 3 | KASL 4 | 5 | ru 6 | Библиотека подсистем КА 7 | 8 | true 9 | true 10 | АТДМассив 11 | 12 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | АТДМассив 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.xtext.ui.shared.xtextBuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.xtext.ui.shared.xtextNature 16 | com._1c.g5.v8.dt.core.V8ExtensionNature 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/CommonModules/РаботаСКоллекцией/РаботаСКоллекцией.mdo: -------------------------------------------------------------------------------- 1 | 2 | 3 | РаботаСКоллекцией 4 | 5 | ru 6 | Работа с коллекцией 7 | 8 | true 9 | true 10 | true 11 | 12 | -------------------------------------------------------------------------------- /src/CommonModules/РаботаСМассивом/РаботаСМассивом.mdo: -------------------------------------------------------------------------------- 1 | 2 | 3 | РаботаСМассивом 4 | 5 | ru 6 | Работа с массивом 7 | 8 | true 9 | true 10 | true 11 | true 12 | 13 | -------------------------------------------------------------------------------- /src/CommonModules/РаботаСОчередью/РаботаСОчередью.mdo: -------------------------------------------------------------------------------- 1 | 2 | 3 | РаботаСОчередью 4 | 5 | ru 6 | Работа с очередью 7 | 8 | true 9 | true 10 | true 11 | true 12 | 13 | -------------------------------------------------------------------------------- /src/CommonModules/РаботаСМножеством/РаботаСМножеством.mdo: -------------------------------------------------------------------------------- 1 | 2 | 3 | РаботаСМножеством 4 | 5 | ru 6 | Работа с множеством 7 | 8 | true 9 | true 10 | true 11 | true 12 | 13 | -------------------------------------------------------------------------------- /src/Subsystems/KASL/Subsystems/АТДМассив/АТДМассив.mdo: -------------------------------------------------------------------------------- 1 | 2 | 3 | АТДМассив 4 | 5 | ru 6 | АТДМассив 7 | 8 | true 9 | DataProcessor.АТДМассив 10 | CommonModule.РаботаСМассивом 11 | CommonModule.РаботаСМножеством 12 | CommonModule.РаботаСОчередью 13 | CommonModule.РаботаСКоллекцией 14 | Subsystem.KASL 15 | 16 | -------------------------------------------------------------------------------- /src/DataProcessors/АТДМассив/АТДМассив.mdo: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | АТДМассив 8 | 9 | ru 10 | Массив 11 | 12 | true 13 | DataProcessor.АТДМассив.Form.Форма 14 | 15 | Форма 16 | 17 | ru 18 | Форма 19 | 20 | PersonalComputer 21 | MobileDevice 22 | 23 | 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Andrey 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/DataProcessors/АТДМассив/Forms/Форма/Form.form: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ФормаКоманднаяПанель 5 | -1 6 | true 7 | true 8 | 9 | true 10 | 11 | Left 12 | true 13 | 14 | 15 | OnOpen 16 | ПриОткрытии 17 | 18 | true 19 | true 20 | true 21 | Vertical 22 | true 23 | true 24 | true 25 | true 26 | true 27 | 28 | Объект 29 | 1 30 | 31 | DataProcessorObject.АТДМассив 32 | 33 | 34 | true 35 | 36 | 37 | true 38 | 39 |
true
40 |
41 | 42 | 43 | 44 | 45 | 46 |
47 | -------------------------------------------------------------------------------- /src/Configuration/Configuration.mdo: -------------------------------------------------------------------------------- 1 | 2 | 3 | АТДМассив 4 | 5 | ru 6 | АТД Массив 7 | 8 | Абстрактные алгоритмы 9 | Adopted 10 | 11 | Checked 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | KASL 21 | 8.3.25 22 | AddOn 23 | ManagedApplication 24 | Russian 25 | Калякин Андрей 26 | 1.1.0.4 27 | 28 | ru 29 | https://infostart.ru/profile/16301/ 30 | 31 | 32 | ru 33 | https://github.com/KalyakinAG/adt-array 34 | 35 | 36 | Русский 37 | Adopted 38 | 39 | Checked 40 | 41 | ru 42 | 43 | Subsystem.KASL 44 | CommonModule.РаботаСКоллекцией 45 | CommonModule.РаботаСМассивом 46 | CommonModule.РаботаСОчередью 47 | CommonModule.РаботаСМножеством 48 | DataProcessor.АТДМассив 49 | 50 | -------------------------------------------------------------------------------- /src/CommonModules/РаботаСМножеством/Module.bsl: -------------------------------------------------------------------------------- 1 | // Подсистема "Абстрактный тип данных массив" 2 | // Автор: Калякин Андрей Г. 3 | // https://github.com/KalyakinAG/adt-array 4 | // https://infostart.ru/1c/articles/1473034/ 5 | 6 | #Область ПрограммныйИнтерфейс 7 | 8 | Функция Множество(Ключ = Неопределено) Экспорт 9 | _Множество = Новый Структура("Ключ, Словарь", Ключ, Новый Соответствие); 10 | Возврат _Множество; 11 | КонецФункции 12 | 13 | Функция Дополнить(__Множество = Неопределено, Элементы) Экспорт 14 | _Множество = ?(__Множество = Неопределено ИЛИ ТипЗнч(__Множество) = Тип("Строка"), Множество(__Множество), __Множество); 15 | Для Каждого Элемент Из Элементы Цикл 16 | Добавить(_Множество, Элемент); 17 | КонецЦикла; 18 | Возврат _Множество; 19 | КонецФункции 20 | 21 | // add 22 | Процедура Добавить(Множество, Элемент) Экспорт 23 | ЗначениеКлюча = ?(ЗначениеЗаполнено(Множество.Ключ), Элемент[Множество.Ключ], Элемент); 24 | Множество.Словарь.Вставить(ЗначениеКлюча, Элемент); 25 | КонецПроцедуры 26 | 27 | // delete 28 | Процедура Удалить(Множество, Элемент) Экспорт 29 | ЗначениеКлюча = ?(ЗначениеЗаполнено(Множество.Ключ), Элемент[Множество.Ключ], Элемент); 30 | Множество.Словарь.Удалить(ЗначениеКлюча); 31 | КонецПроцедуры 32 | 33 | // has 34 | Функция Содержит(Множество, Элемент, Значение = Неопределено) Экспорт 35 | ЗначениеКлюча = ?(ЗначениеЗаполнено(Множество.Ключ), Элемент[Множество.Ключ], Элемент); 36 | Значение = Множество.Словарь[ЗначениеКлюча]; 37 | Возврат Значение <> Неопределено; 38 | КонецФункции 39 | 40 | // isEmpty 41 | Функция Пустое(Множество) Экспорт 42 | Возврат НЕ ЗначениеЗаполнено(Множество.Словарь); 43 | КонецФункции 44 | 45 | Функция Пересечение(Множество1, Множество2) Экспорт 46 | Результат = Множество(Множество1.Ключ); 47 | Для Каждого КлючЗначение Из Множество1.Словарь Цикл 48 | Значение = КлючЗначение.Значение; 49 | Если НЕ Содержит(Множество2, Значение) Тогда 50 | Продолжить; 51 | КонецЕсли; 52 | Добавить(Результат, Значение); 53 | КонецЦикла; 54 | Возврат Результат; 55 | КонецФункции 56 | 57 | Функция Разность(Множество1, Множество2) Экспорт 58 | Результат = Множество(Множество1.Ключ); 59 | Для Каждого КлючЗначение Из Множество1.Словарь Цикл 60 | Значение = КлючЗначение.Значение; 61 | Если Содержит(Множество2, Значение) Тогда 62 | Продолжить; 63 | КонецЕсли; 64 | Добавить(Результат, Значение); 65 | КонецЦикла; 66 | Возврат Результат; 67 | КонецФункции 68 | 69 | Функция Объединение(Множество1, Множество2) Экспорт 70 | Результат = Множество(Множество1.Ключ); 71 | Для Каждого КлючЗначение Из Множество1.Словарь Цикл 72 | Добавить(Результат, КлючЗначение.Значение); 73 | КонецЦикла; 74 | Возврат Результат; 75 | КонецФункции 76 | 77 | Функция Массив(Множество) Экспорт 78 | Результат = Новый Массив; 79 | Для Каждого КлючЗначение Из Множество.Словарь Цикл 80 | Результат.Добавить(КлючЗначение.Значение); 81 | КонецЦикла; 82 | Возврат Результат; 83 | КонецФункции 84 | 85 | #КонецОбласти -------------------------------------------------------------------------------- /src/CommonModules/РаботаСОчередью/Module.bsl: -------------------------------------------------------------------------------- 1 | // Подсистема "Абстрактный тип данных массив" 2 | // Автор: Калякин Андрей Г. 3 | // https://github.com/KalyakinAG/adt-array 4 | // https://infostart.ru/1c/articles/1473034/ 5 | 6 | #Область ПрограммныйИнтерфейс 7 | 8 | // Параметры: 9 | // Ключ - Строка - имя свойства объекта. Определяется для очереди с уникальными элементами 10 | // ФункцияСравнения - Строка - . Определяется для очереди с приоритетом 11 | Функция Очередь(ЕстьУникальность = Ложь, ЕстьПриоритет = Ложь, Ключ = Неопределено, ФункцияСравнения = Неопределено, Контекст = Неопределено, Параметры = Неопределено) Экспорт 12 | Результат = Новый Структура("Элементы, ЕстьПриоритет, ЕстьУникальность, Контекст, Параметры", Новый Массив, ЕстьПриоритет, ЕстьУникальность); 13 | Если ЕстьПриоритет Тогда 14 | Результат.Вставить("ФункцияСравнения", ФункцияСравнения); 15 | Результат.Вставить("Контекст", Контекст); 16 | Результат.Вставить("Параметры", Параметры); 17 | КонецЕсли; 18 | Если ЕстьУникальность Тогда 19 | Результат.Вставить("Словарь", РаботаСМножеством.Множество(Ключ)); 20 | Результат.Вставить("Ключ", Ключ); 21 | КонецЕсли; 22 | Возврат Результат; 23 | КонецФункции 24 | 25 | Функция ОчередьУникальныхЗначений(Ключ = Неопределено) Экспорт 26 | Возврат Очередь(Истина, Ложь, Ключ); 27 | КонецФункции 28 | 29 | // Параметры: 30 | // Ключ - Строка - имя свойства объекта. Определяется для очереди с уникальными элементами 31 | // ФункцияСравнения - Строка - . Определяется для очереди с приоритетом 32 | Функция ПриоритетнаяОчередь(ФункцияСравнения, Контекст = Неопределено, Параметры = Неопределено) Экспорт 33 | Возврат Очередь(Ложь, Истина, , ФункцияСравнения, Контекст, Параметры); 34 | КонецФункции 35 | 36 | Функция ПриоритетнаяОчередьУникальныхЗначений(ФункцияСравнения, Ключ = Неопределено, Контекст = Неопределено, Параметры = Неопределено) Экспорт 37 | Возврат Очередь(Истина, Истина, Ключ, ФункцияСравнения, Контекст, Параметры); 38 | КонецФункции 39 | 40 | Процедура Положить(Очередь, Элемент) Экспорт 41 | Если Очередь.ЕстьУникальность Тогда 42 | Если РаботаСМножеством.Содержит(Очередь.Словарь, Элемент) Тогда 43 | Возврат; 44 | КонецЕсли; 45 | РаботаСМножеством.Добавить(Очередь.Словарь, Элемент); 46 | КонецЕсли; 47 | Если Очередь.ЕстьПриоритет Тогда 48 | РаботаСМассивом.ПоложитьВОчередьСПриоритетом(Очередь.Элементы, Элемент, Очередь.ФункцияСравнения, Очередь.Контекст, Очередь.Параметры); 49 | Иначе 50 | РаботаСМассивом.Положить(Очередь.Элементы, Элемент); 51 | КонецЕсли; 52 | КонецПроцедуры 53 | 54 | Процедура Добавить(Очередь, Элемент) Экспорт 55 | Положить(Очередь, Элемент); 56 | КонецПроцедуры 57 | 58 | Процедура Дополнить(_Множество, Элементы) Экспорт 59 | Для Каждого Элемент Из Элементы Цикл 60 | Положить(_Множество, Элемент); 61 | КонецЦикла; 62 | КонецПроцедуры 63 | 64 | // isEmpty 65 | Функция Пустая(Очередь) Экспорт 66 | Возврат НЕ ЗначениеЗаполнено(Очередь.Элементы); 67 | КонецФункции 68 | 69 | // pop 70 | Функция Взять(Очередь) Экспорт 71 | Элемент = РаботаСМассивом.Взять(Очередь.Элементы); 72 | Если Очередь.ЕстьУникальность Тогда 73 | РаботаСМножеством.Удалить(Очередь.Словарь, Элемент); 74 | КонецЕсли; 75 | Возврат Элемент; 76 | КонецФункции 77 | 78 | // shift 79 | Функция Сдвинуть(Очередь) Экспорт 80 | Элемент = РаботаСМассивом.Сдвинуть(Очередь.Элементы); 81 | Если Очередь.ЕстьУникальность Тогда 82 | РаботаСМножеством.Удалить(Очередь.Словарь, Элемент); 83 | КонецЕсли; 84 | Возврат Элемент; 85 | КонецФункции 86 | 87 | // has 88 | Функция Содержит(Очередь, Элемент) Экспорт 89 | Если Очередь.ЕстьУникальность Тогда 90 | Возврат РаботаСМножеством.Содержит(Очередь.Словарь, Элемент); 91 | КонецЕсли; 92 | Если Очередь.ЕстьПриоритет Тогда 93 | Возврат РаботаСМассивом.НайтиЭлементОчередиСПриоритетом(Очередь.Элементы, Элемент, 0, Очередь.Элементы.Количество(), Очередь.ФункцияСравнения); 94 | КонецЕсли; 95 | Возврат РаботаСМассивом.НайтиЭлемент(Очередь.Элементы, "Элемент = Параметры", , Элемент) <> Неопределено; 96 | КонецФункции 97 | 98 | #КонецОбласти 99 | 100 | #Область СлужебныеПроцедурыИФункции 101 | 102 | #КонецОбласти 103 | -------------------------------------------------------------------------------- /src/DataProcessors/АТДМассив/Forms/Форма/Module.bsl: -------------------------------------------------------------------------------- 1 | // Подсистема "Абстрактный тип данных массив" 2 | // Автор: Калякин Андрей Г. 3 | // https://github.com/KalyakinAG/adt-array 4 | // https://infostart.ru/1c/articles/1473034/ 5 | 6 | &НаКлиенте 7 | Перем ЭлементыМассива; 8 | 9 | // Преобразует переданные элементы в массив 10 | // 11 | // Параметры: 12 | // НовыеЭлементы - массив - Коллекция элементов, для которой доступен обход ДляКаждого. 13 | // Если параметр не задан, то преобразуется текущая коллекция в массив элементов. 14 | // 15 | // Возвращаемое значение: 16 | // ОбработкаОбъект.АТДМассив - Массив 17 | &НаКлиенте 18 | Функция Массив(НовыеЭлементы = Неопределено) Экспорт 19 | Если НовыеЭлементы = Неопределено Тогда 20 | Если ТипЗнч(ЭлементыМассива) = Тип("Массив") Тогда 21 | Возврат ЭтотОбъект; 22 | КонецЕсли; 23 | ЭлементыМассива = ОбщегоНазначенияКлиентСервер.СкопироватьМассив(ЭлементыМассива); 24 | Возврат ЭтотОбъект; 25 | КонецЕсли; 26 | ЭлементыМассива = ОбщегоНазначенияКлиентСервер.СкопироватьМассив(НовыеЭлементы); 27 | Возврат ЭтотОбъект; 28 | КонецФункции 29 | 30 | &НаКлиенте 31 | Функция Установить(Элементы) Экспорт 32 | ЭлементыМассива = Элементы; 33 | Возврат ЭтотОбъект; 34 | КонецФункции 35 | 36 | &НаКлиенте 37 | Функция ВМассив() Экспорт 38 | Если ТипЗнч(ЭлементыМассива) <> Тип("Массив") Тогда 39 | Массив(); 40 | КонецЕсли; 41 | Возврат ЭлементыМассива; 42 | КонецФункции 43 | 44 | &НаКлиенте 45 | Функция ВСписокЗначений() Экспорт 46 | Список = Новый СписокЗначений; 47 | Список.ЗагрузитьЗначения(ВМассив()); 48 | Возврат Список; 49 | КонецФункции 50 | 51 | &НаКлиенте 52 | Функция ВФиксированныйМассив() Экспорт 53 | Возврат Новый ФиксированныйМассив(ВМассив()); 54 | КонецФункции 55 | 56 | // filter 57 | &НаКлиенте 58 | Функция Отобрать(ВыражениеПредиката, Контекст = Неопределено, Параметры = Неопределено) Экспорт 59 | ЭлементыМассива = РаботаСМассивом.Отобрать(ЭлементыМассива, ВыражениеПредиката, Контекст, Параметры); 60 | Возврат ЭтотОбъект; 61 | КонецФункции 62 | 63 | // find 64 | &НаКлиенте 65 | Функция НайтиЭлемент(ВыражениеПредиката, Контекст = Неопределено, Параметры = Неопределено) Экспорт 66 | Возврат РаботаСМассивом.НайтиЭлемент(ЭлементыМассива, ВыражениеПредиката, Контекст, Параметры); 67 | КонецФункции 68 | 69 | // sortBy 70 | // Пример: 71 | //Фрукты = Общий.АТДМассив(СтрРазделить("вишня, арбузы, бананы", ", ", Ложь)); 72 | //Фрукты.Сортировать(); 73 | //Фрукты.ДляКаждого("Сообщить(Элемент)");// [арбузы, бананы, вишня] 74 | // 75 | // Параметры: 76 | // ВыражениеПредиката - Строка 77 | // Контекст - Неопределено - Контекст 78 | // 79 | // Возвращаемое значение: 80 | // ОбработкаОбъект.АТДМассив - Сортировать 81 | &НаКлиенте 82 | Функция СортироватьПо(Поля) Экспорт 83 | РаботаСМассивом.СортироватьПо(ЭлементыМассива, Поля); 84 | Возврат ЭтотОбъект; 85 | КонецФункции 86 | 87 | // sort 88 | // Пример: 89 | //Фрукты = Общий.АТДМассив(СтрРазделить("вишня, арбузы, бананы", ", ", Ложь)); 90 | //Фрукты.Сортировать(); 91 | //Фрукты.ДляКаждого("Сообщить(Элемент)");// [арбузы, бананы, вишня] 92 | // 93 | // Параметры: 94 | // ВыражениеПредиката - Строка 95 | // Контекст - Неопределено - Контекст 96 | // 97 | // Возвращаемое значение: 98 | // ОбработкаОбъект.АТДМассив - Сортировать 99 | &НаКлиенте 100 | Функция Сортировать(ВыражениеПредиката = Неопределено, Контекст = Неопределено, Параметры = Неопределено) Экспорт 101 | РаботаСМассивом.Сортировать(ЭлементыМассива, ВыражениеПредиката, Контекст, Параметры); 102 | Возврат ЭтотОбъект; 103 | КонецФункции 104 | 105 | // map 106 | // 107 | // Параметры: 108 | // Выражение - Строка - Выражение функции 109 | // Контекст - Неопределено - Контекст 110 | // Параметры - Неопределено - Параметры 111 | // 112 | // Возвращаемое значение: 113 | // ОбработкаОбъект.АТДМассив - Отобразить 114 | &НаКлиенте 115 | Функция Отобразить(Выражение, Контекст = Неопределено, Параметры = Неопределено) Экспорт 116 | ЭлементыМассива = РаботаСМассивом.Отобразить(ЭлементыМассива, Выражение, Контекст, Параметры); 117 | Возврат ЭтотОбъект; 118 | КонецФункции 119 | 120 | // reduce 121 | // 122 | // Параметры: 123 | // Выражение - Строка - Выражение функции 124 | // НачальноеЗначение - Неопределено - Начальное значение 125 | // Контекст - Неопределено - Контекст 126 | // Параметры - Неопределено - Параметры 127 | // 128 | // Возвращаемое значение: 129 | // Произвольный - Преобразовать 130 | &НаКлиенте 131 | Функция Преобразовать(Выражение, НачальноеЗначение = Неопределено, Контекст = Неопределено, Параметры = Неопределено) Экспорт 132 | Возврат РаботаСМассивом.Преобразовать(ЭлементыМассива, Выражение, НачальноеЗначение, Контекст, Параметры); 133 | КонецФункции 134 | 135 | // pop 136 | &НаКлиенте 137 | Функция Взять() Экспорт 138 | Возврат РаботаСМассивом.Взять(ЭлементыМассива); 139 | КонецФункции 140 | 141 | // push 142 | &НаКлиенте 143 | Функция Положить(Элемент) Экспорт 144 | РаботаСМассивом.Положить(ЭлементыМассива, Элемент); 145 | Возврат ЭтотОбъект; 146 | КонецФункции 147 | 148 | // add 149 | &НаКлиенте 150 | Функция Добавить(Элемент) Экспорт 151 | РаботаСМассивом.Добавить(ЭлементыМассива, Элемент); 152 | Возврат ЭтотОбъект; 153 | КонецФункции 154 | 155 | // insert 156 | &НаКлиенте 157 | Функция Вставить(Индекс, Элемент) Экспорт 158 | ЭлементыМассива.Вставить(Индекс, Элемент); 159 | Возврат ЭтотОбъект; 160 | КонецФункции 161 | 162 | // slice 163 | &НаКлиенте 164 | Функция Срез(НижняяГраница = 0, Знач ВерхняяГраница = Неопределено, Шаг = 1) Экспорт 165 | ЭлементыМассива = РаботаСМассивом.Срез(ЭлементыМассива, НижняяГраница, ВерхняяГраница, Шаг); 166 | Возврат ЭтотОбъект; 167 | КонецФункции 168 | 169 | #Если НЕ ВебКлиент Тогда 170 | 171 | // forEach 172 | &НаКлиенте 173 | Функция ДляКаждого(Алгоритм, Контекст = Неопределено, Параметры = Неопределено) Экспорт 174 | РаботаСМассивом.ДляКаждого(ЭлементыМассива, Алгоритм, Контекст, Параметры); 175 | Возврат ЭтотОбъект; 176 | КонецФункции 177 | 178 | #КонецЕсли 179 | 180 | &НаКлиенте 181 | Функция ДополнитьМассив(МассивИсточник, ТолькоУникальныеЗначения = Ложь) Экспорт 182 | РаботаСМассивом.ДополнитьМассив(ЭлементыМассива, МассивИсточник, ТолькоУникальныеЗначения); 183 | Возврат ЭтотОбъект; 184 | КонецФункции 185 | 186 | &НаКлиенте 187 | Функция Пустой() Экспорт 188 | Возврат ЭлементыМассива.Количество() = 0; 189 | КонецФункции 190 | 191 | &НаКлиенте 192 | Процедура ПриОткрытии(Отказ) 193 | Отказ = Истина; 194 | Сообщить("Обработка не предназначена для работы в интерактивном режиме!"); 195 | КонецПроцедуры 196 | 197 | ЭлементыМассива = Новый Массив; 198 | -------------------------------------------------------------------------------- /src/DataProcessors/АТДМассив/ObjectModule.bsl: -------------------------------------------------------------------------------- 1 | // Подсистема "Абстрактный тип данных массив" 2 | // Автор: Калякин Андрей Г. 3 | // https://github.com/KalyakinAG/adt-array 4 | // https://infostart.ru/1c/articles/1473034/ 5 | 6 | Перем ЭлементыМассива; 7 | 8 | // Преобразует переданные элементы в массив 9 | // 10 | // Параметры: 11 | // НовыеЭлементы - массив - Коллекция элементов, для которой доступен обход ДляКаждого. 12 | // Если параметр не задан, то преобразуется текущая коллекция в массив элементов. 13 | // 14 | // Возвращаемое значение: 15 | // ОбработкаОбъект.АТДМассив - Массив 16 | Функция Массив(НовыеЭлементы = Неопределено) Экспорт 17 | Если НовыеЭлементы = Неопределено Тогда 18 | Если ТипЗнч(ЭлементыМассива) = Тип("Массив") Тогда 19 | Возврат ЭтотОбъект; 20 | КонецЕсли; 21 | ЭлементыМассива = ОбщегоНазначенияКлиентСервер.СкопироватьМассив(ЭлементыМассива); 22 | Возврат ЭтотОбъект; 23 | КонецЕсли; 24 | ЭлементыМассива = ОбщегоНазначенияКлиентСервер.СкопироватьМассив(НовыеЭлементы); 25 | Возврат ЭтотОбъект; 26 | КонецФункции 27 | 28 | Функция Установить(Элементы) Экспорт 29 | ЭлементыМассива = Элементы; 30 | Возврат ЭтотОбъект; 31 | КонецФункции 32 | 33 | Функция ВМассив(Свернуть = Ложь) Экспорт 34 | Если ТипЗнч(ЭлементыМассива) <> Тип("Массив") Тогда 35 | Массив(); 36 | КонецЕсли; 37 | Если Свернуть Тогда 38 | ЭлементыМассива = ОбщегоНазначенияКлиентСервер.СвернутьМассив(ЭлементыМассива); 39 | КонецЕсли; 40 | Возврат ЭлементыМассива; 41 | КонецФункции 42 | 43 | Функция ВСписокЗначений() Экспорт 44 | Список = Новый СписокЗначений; 45 | Список.ЗагрузитьЗначения(ВМассив()); 46 | Возврат Список; 47 | КонецФункции 48 | 49 | Функция ВФиксированныйМассив() Экспорт 50 | Возврат Новый ФиксированныйМассив(ВМассив()); 51 | КонецФункции 52 | 53 | // flat 54 | Функция Спрямить(Глубина = Неопределено) Экспорт 55 | ЭлементыМассива = РаботаСМассивом.Спрямить(ЭлементыМассива, Глубина); 56 | Возврат ЭтотОбъект; 57 | КонецФункции 58 | 59 | // filter 60 | Функция Отобрать(ВыражениеПредиката, Контекст = Неопределено, Параметры = Неопределено) Экспорт 61 | ЭлементыМассива = РаботаСМассивом.Отобрать(ЭлементыМассива, ВыражениеПредиката, Контекст, Параметры); 62 | Возврат ЭтотОбъект; 63 | КонецФункции 64 | 65 | // find 66 | Функция НайтиЭлемент(ВыражениеПредиката, Контекст = Неопределено, Параметры = Неопределено) Экспорт 67 | Возврат РаботаСМассивом.НайтиЭлемент(ЭлементыМассива, ВыражениеПредиката, Контекст, Параметры); 68 | КонецФункции 69 | 70 | // sortBy 71 | // Пример: 72 | //Фрукты = Общий.АТДМассив(СтрРазделить("вишня, арбузы, бананы", ", ", Ложь)); 73 | //Фрукты.Сортировать(); 74 | //Фрукты.ДляКаждого("Сообщить(Элемент)");// [арбузы, бананы, вишня] 75 | // 76 | // Параметры: 77 | // ВыражениеПредиката - Строка 78 | // Контекст - Неопределено - Контекст 79 | // 80 | // Возвращаемое значение: 81 | // ОбработкаОбъект.АТДМассив - Сортировать 82 | Функция СортироватьПо(Поля) Экспорт 83 | РаботаСМассивом.СортироватьПо(ЭлементыМассива, Поля); 84 | Возврат ЭтотОбъект; 85 | КонецФункции 86 | 87 | // sort 88 | // Пример: 89 | //Фрукты = Общий.АТДМассив(СтрРазделить("вишня, арбузы, бананы", ", ", Ложь)); 90 | //Фрукты.Сортировать(); 91 | //Фрукты.ДляКаждого("Сообщить(Элемент)");// [арбузы, бананы, вишня] 92 | // 93 | // Параметры: 94 | // ВыражениеПредиката - Строка 95 | // Контекст - Неопределено - Контекст 96 | // 97 | // Возвращаемое значение: 98 | // ОбработкаОбъект.АТДМассив - Сортировать 99 | Функция Сортировать(ВыражениеПредиката = Неопределено, Контекст = Неопределено, Параметры = Неопределено) Экспорт 100 | РаботаСМассивом.Сортировать(ЭлементыМассива, ВыражениеПредиката, Контекст, Параметры); 101 | Возврат ЭтотОбъект; 102 | КонецФункции 103 | 104 | Функция ОпределитьТопографическийПорядок(Ключ = "Идентификатор", СвойствоПодчиненныхЭлементов = "ПодчиненныеЭлементы", СвойствоПорядка = "Порядок", Словарь = Неопределено) Экспорт 105 | РаботаСМассивом.ОпределитьТопографическийПорядок(ЭлементыМассива, Ключ, СвойствоПодчиненныхЭлементов, СвойствоПорядка, Словарь); 106 | Возврат ЭтотОбъект; 107 | КонецФункции 108 | 109 | // map 110 | // 111 | // Параметры: 112 | // Выражение - Строка - Выражение функции 113 | // Контекст - Неопределено - Контекст 114 | // Параметры - Неопределено - Параметры 115 | // 116 | // Возвращаемое значение: 117 | // ОбработкаОбъект.АТДМассив - Отобразить 118 | Функция Отобразить(Выражение, Контекст = Неопределено, Параметры = Неопределено) Экспорт 119 | ЭлементыМассива = РаботаСМассивом.Отобразить(ЭлементыМассива, Выражение, Контекст, Параметры); 120 | Возврат ЭтотОбъект; 121 | КонецФункции 122 | 123 | // reduce 124 | // 125 | // Параметры: 126 | // Выражение - Строка - Выражение функции 127 | // НачальноеЗначение - Неопределено - Начальное значение 128 | // Контекст - Неопределено - Контекст 129 | // Параметры - Неопределено - Параметры 130 | // 131 | // Возвращаемое значение: 132 | // Произвольный - Преобразовать 133 | Функция Преобразовать(Выражение, НачальноеЗначение = Неопределено, Контекст = Неопределено, Параметры = Неопределено) Экспорт 134 | Возврат РаботаСМассивом.Преобразовать(ЭлементыМассива, Выражение, НачальноеЗначение, Контекст, Параметры); 135 | КонецФункции 136 | 137 | // pop 138 | Функция Взять() Экспорт 139 | Возврат РаботаСМассивом.Взять(ЭлементыМассива); 140 | КонецФункции 141 | 142 | // push 143 | Функция Положить(Элемент) Экспорт 144 | РаботаСМассивом.Положить(ЭлементыМассива, Элемент); 145 | Возврат ЭтотОбъект; 146 | КонецФункции 147 | 148 | // insert 149 | Функция Вставить(Индекс, Элемент) Экспорт 150 | ЭлементыМассива.Вставить(Индекс, Элемент); 151 | Возврат ЭтотОбъект; 152 | КонецФункции 153 | 154 | // add 155 | Функция Добавить(Элемент) Экспорт 156 | РаботаСМассивом.Добавить(ЭлементыМассива, Элемент); 157 | Возврат ЭтотОбъект; 158 | КонецФункции 159 | 160 | // slice 161 | Функция Срез(НижняяГраница = 0, Знач ВерхняяГраница = Неопределено, Шаг = 1) Экспорт 162 | ЭлементыМассива = РаботаСМассивом.Срез(ЭлементыМассива, НижняяГраница, ВерхняяГраница, Шаг); 163 | Возврат ЭтотОбъект; 164 | КонецФункции 165 | 166 | #Если НЕ ВебКлиент Тогда 167 | 168 | // forEach 169 | Функция ДляКаждого(Алгоритм, Контекст = Неопределено, Параметры = Неопределено) Экспорт 170 | РаботаСМассивом.ДляКаждого(ЭлементыМассива, Алгоритм, Контекст, Параметры); 171 | Возврат ЭтотОбъект; 172 | КонецФункции 173 | 174 | #КонецЕсли 175 | 176 | Функция ДополнитьМассив(МассивИсточник, ТолькоУникальныеЗначения = Ложь) Экспорт 177 | Дополнить(МассивИсточник, ТолькоУникальныеЗначения); 178 | Возврат ЭтотОбъект; 179 | КонецФункции 180 | 181 | Функция Дополнить(МассивИсточник, ТолькоУникальныеЗначения = Ложь) Экспорт 182 | ЭлементыМассива = РаботаСМассивом.Дополнить(ЭлементыМассива, МассивИсточник, ТолькоУникальныеЗначения); 183 | Возврат ЭтотОбъект; 184 | КонецФункции 185 | 186 | Функция Разность(МассивВычитания) Экспорт 187 | ЭлементыМассива = РаботаСМассивом.Разность(ЭлементыМассива, МассивВычитания); 188 | Возврат ЭтотОбъект; 189 | КонецФункции 190 | 191 | Функция Свернуть() Экспорт 192 | ЭлементыМассива = РаботаСМассивом.Свернуть(ЭлементыМассива); 193 | Возврат ЭтотОбъект; 194 | КонецФункции 195 | 196 | Функция Пустой() Экспорт 197 | Возврат ЭлементыМассива.Количество() = 0; 198 | КонецФункции 199 | 200 | ЭлементыМассива = Новый Массив; 201 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Работа с массивом как с абстрактным типом данных на 1С 2 | 3 | [![OpenYellow](https://img.shields.io/endpoint?url=https://openyellow.org/data/badges/1/382631462.json)](https://openyellow.org/grid?data=top&repo=382631462) ![Версия](https://img.shields.io/badge/Версия_1С-8.3.25-yellow) 4 | 5 | Реализована библиотека по работе с массивом. В библиотеке доступны абстрактные функции: Отобрать (filter), НайтиЭлемент (find), Сортировать (sort), Отобразить (map), Преобразовать (reduce), Взять (pop), Положить (push), ДляКаждого (forEach). 6 | 7 | Функции библиотеки доступны в серверном и клиентском контекстах. 8 | 9 | Реализована также и объектная модель АТД массива. Объектная модель позволяет использовать при работе с АТД массивом текучий интерфейс. 10 | 11 | [![Модель запроса](https://infostart.ru/bitrix/templates/sandbox_empty/assets/tpl/abo/img/logo.svg)](infostart.ru/1c/articles/1473034/) 12 | ### Оглавление: 13 | - [Примеры](#примеры) 14 | - [Конструктор](#конструктор) 15 | - [Сортировать (sort)](#сортировать-sort) 16 | - [Отобрать (filter)](#отобрать-filter) 17 | - [Отобразить (map)](#отобразить-map) 18 | - [Преобразовать (reduce)](#преобразовать-reduce) 19 | - [Еще примеры](#еще-примеры) 20 | - [Совместно с БСП](#совместно-с-бсп) 21 | - [Пример использования оператора Спрямить (flat)](#пример-использования-оператора-спрямить-flat) 22 | - [Пример использования абстракций Диапазон и Срез](#пример-использования-абстракций-диапазон-и-срез) 23 | - [Состав и установка](#состав-и-установка) 24 | - [Установить как расширение](#установить-как-расширение) 25 | - [Объединить с конфигурацией текущего проекта](#объединить-с-конфигурацией-текущего-проекта) 26 | - [Объединить с конфигурацией проекта KASL](#объединить-с-конфигурацией-проекта-kasl) 27 | - [Зависимости](#зависимости) 28 | 29 | ## Примеры 30 | 31 | Больше примеров смотрите в статьях: 32 | - [Работа с абстрактным массивом](https://infostart.ru/1c/articles/1473034/) 33 | - [Абстрактные типы, множества, очереди. Примеры использования](https://infostart.ru/1c/2093459/) 34 | 35 | ### Конструктор 36 | 37 | ```bsl 38 | Фрукты = РаботаСМассивом.АТДМассив(СтрРазделить("вишня, арбузы, бананы", ", ", Ложь)); 39 | Фрукты.ДляКаждого("Сообщить(Элемент)");// [вишня, арбузы, бананы] 40 | ``` 41 | ### Сортировать (sort) 42 | 43 | ```bsl 44 | Фрукты.Сортировать(); 45 | Фрукты.ДляКаждого("Сообщить(Элемент)");// [арбузы, бананы, вишня] 46 | ``` 47 | ### Отобрать (filter) 48 | 49 | ```bsl 50 | Фрукты.Отобрать("СтрНайти(Элемент, ""а"") > 0"); 51 | Фрукты.ДляКаждого("Сообщить(Элемент)");// [арбузы, бананы] 52 | ``` 53 | ### Отобразить (map) 54 | 55 | ```bsl 56 | Фрукты.Отобразить("ВРег(Лев(Элемент, 1)) + Прав(Элемент, СтрДлина(Элемент) - 1)"); 57 | Фрукты.ДляКаждого("Сообщить(Элемент)");// [Арбузы, Бананы] 58 | ``` 59 | ### Преобразовать (reduce) 60 | 61 | ```bsl 62 | Количество = Фрукты.Преобразовать("Накопитель + 1", 0); 63 | Сообщить(Количество);// 2 64 | ``` 65 | ### Еще примеры 66 | 67 | ```bsl 68 | // Настройка связей элементов формы 69 | Элементы.ДоговорКонтрагентов.СвязиПараметровВыбора = РаботаСМассивом.АТДМассив() 70 | .Положить(Новый СвязьПараметраВыбора("Отбор.Владелец", "Объект.Организация")) 71 | .ВФиксированныйМассив() 72 | ; 73 | // Конструктор описания типов на основе массива типов 74 | ДопустимыеТипы = Новый ОписаниеТипов(РаботаСМассивом.АТДМассив() 75 | .Положить(Тип("СправочникСсылка._ДемоНоменклатура")) 76 | .Положить(ОбщегоНазначения.ОписаниеТипаСтрока(20)) 77 | .ВМассив()) 78 | ; 79 | // Сортировка по ФИО 80 | Сотрудники = РаботаСМассивом.АТДМассив() 81 | .Положить(Новый Структура("Фамилия, Имя, Отчество", "Иванов", "Иван", "Иванович")) 82 | .Положить(Новый Структура("Фамилия, Имя, Отчество", "Иванов", "Иван", "Гермагенович")) 83 | .Положить(Новый Структура("Фамилия, Имя, Отчество", "Савельев", "Иван", "Иванович")) 84 | .Положить(Новый Структура("Фамилия, Имя, Отчество", "Андреев", "Иван", "Иванович")) 85 | .Положить(Новый Структура("Фамилия, Имя, Отчество", "Андреев", "Андрей", "Андреевич")) 86 | ; 87 | Сотрудники.СортироватьПо("Фамилия, Имя, Отчество"); 88 | Сотрудники.ДляКаждого("Сообщить(СтрШаблон(""%1 %2 %3"", Элемент.Фамилия, Элемент.Имя, Элемент.Отчество))"); // [Андреев Андрей Андреевич, Андреев Иван Иванович, Иванов Иван Гермагенович, Иванов Иван Иванович, Савельев Иван Иванович] 89 | // Список пользователей с полными правами 90 | СписокПользователей = РаботаСМассивом.АТДМассив(ПользователиИнформационнойБазы.ПолучитьПользователей()) 91 | .Отобрать("Элемент.Роли.Содержит(Метаданные.Роли.ПолныеПрава)") 92 | .Отобразить("Элемент.Имя") 93 | .ВМассив() 94 | ; 95 | Сообщить(ОбщийКлиентСервер.ЗначениеВJSON(СписокПользователей)); 96 | ``` 97 | ### Совместно с БСП 98 | 99 | ```bsl 100 | Файлы = Новый Массив; 101 | РаботаСФайлами.ЗаполнитьПрисоединенныеФайлыКОбъекту(СсылкаНаДокумент, Файлы); 102 | СсылкаНаПрисоединенныйФайл = РаботаСМассивом.АТДМассив(Файлы) 103 | .Отобрать("СтрНайти(Элемент.Наименование, ""#БДДС#"") > 0") 104 | .Отобрать("НЕ Элемент.ПометкаУдаления") 105 | .Взять() 106 | ; 107 | ``` 108 | ### Пример использования оператора Спрямить (flat) 109 | 110 | ```bsl 111 | МетаданныеРасширений = РаботаСМассивом.АТДМассив(СтрРазделить("Константы, Справочники, Документы, РегистрыСведений, РегистрыНакопления", ", ", Ложь)) 112 | .Отобразить("РаботаСМассивом.АТДМассив(Метаданные[Элемент]).Отобрать(""Элемент.РасширениеКонфигурации() <> Неопределено"").ВМассив()") 113 | .Спрямить() 114 | .Отобразить("Новый Структура(""ПолноеИмя, Расширение"", Элемент.ПолноеИмя(), Элемент.РасширениеКонфигурации().Имя)") 115 | .Отобрать("НЕ СтрНачинаетсяС(Элемент.ПолноеИмя, ""Константа."")") 116 | .ВМассив() 117 | ; 118 | Сообщить(ОбщийКлиентСервер.ОбъектВJSON(МетаданныеРасширений)); 119 | ``` 120 | ### Пример использования абстракций Диапазон и Срез 121 | 122 | ```bsl 123 | //  Создание массива чисел от 1 до 100 124 | ИсходныйМассив = РаботаСМассивом.Диапазон(1, 101); 125 | Сообщить(ОбщийКлиентСервер.ОбъектВJSON(ИсходныйМассив)); 126 | //  Формирование подмассивов по 10 чисел 127 | Шаг = 10; 128 | Для Каждого Индекс Из РаботаСМассивом.Диапазон(0, 100, Шаг) Цикл 129 |     Срез = РаботаСМассивом.Срез(ИсходныйМассив, Индекс, Индекс + Шаг); 130 |     Сообщить(ОбщийКлиентСервер.ОбъектВJSON(Срез)); 131 | КонецЦикла; 132 | ``` 133 | 134 | ### Группировка 135 | 136 | В примере группируются банковские счета по настройкам обмена. На выходе получается словарь настроек и массив счетов. 137 | 138 | ```bsl 139 | НастройкиОбмена = РаботаСМассивом.Преобразовать( 140 | БанковскиеСчета, 141 | "ОбщийКлиентСервер.ВставитьСвойство( 142 | |НачальноеЗначение, Элемент.НастройкаОбмена, 143 | | РаботаСМассивом.Добавить(ОбщийКлиентСервер.ЕстьПустоеЗначение(НачальноеЗначение[Элемент.НастройкаОбмена], Новый Массив), Элемент) 144 | |)", 145 | Новый Соответствие 146 | ); 147 | ``` 148 | Здесь БанковскиеСчета это таблица значений. Если нужен тот же сереализуемый результат: 149 | 150 | ```bsl 151 | НастройкиОбмена = РаботаСМассивом.Преобразовать( 152 | ОбщегоНазначения.ТаблицаЗначенийВМассив(БанковскиеСчета), 153 | "ОбщийКлиентСервер.ВставитьСвойство( 154 | |НачальноеЗначение, Элемент.НастройкаОбмена, 155 | | РаботаСМассивом.Добавить(ОбщийКлиентСервер.ЕстьПустоеЗначение(НачальноеЗначение[Элемент.НастройкаОбмена], Новый Массив), Элемент) 156 | |)", 157 | Новый Соответствие 158 | ); 159 | ``` 160 | ## Состав и установка 161 | 162 | Состав: 163 | - Конфигурация (этот проект): 164 | - модуль библиотеки *РаботаСМассивом* 165 | - обработка *АТДМассив*, реализующая объектный интерфейс 166 | 167 | Есть несколько вариантов установки: 168 | 1. Установить как расширение 169 | 2. Объединить с конфигурацией текущего проекта 170 | 3. Объединить с конфигурацией проекта KASL 171 | 172 | Далее подробнее. 173 | ### Установить как расширение 174 | 175 | Скачать расширение из последнего релиза проекта и установить в базу. 176 | Требуется также установить расширения проектов из [зависимостей](#зависимости). 177 | ### Объединить с конфигурацией текущего проекта 178 | 179 | Объединить с файлом конфигурации из последнего релиза проекта: 180 | - Снять признак объединения с общих свойств 181 | - Установить режим объединения с приоритетом в файле 182 | Требуется также установить расширения проектов из [зависимостей](#зависимости). 183 | ### Объединить с конфигурацией проекта KASL 184 | 185 | Объединить с файлом конфигурации из Демо-базы к статье [Работа с абстрактным массивом](https://infostart.ru/1c/articles/1473034/) или с конфигурацией **KASL.cf** из релиза: 186 | - Установить режим объединения с приоритетом в файле 187 | - Отметить по подсистемам файла: 188 | - KASL->[ОбщегоНазначения](https://github.com/KalyakinAG/common) 189 | - KASL->[АТДМассив](https://github.com/KalyakinAG/adt-array) 190 | ## Зависимости 191 | 192 | - БСП (работает с версией 3 и выше) 193 | - Общие модули из подсистемы [KASL->ОбщегоНазначения](https://github.com/KalyakinAG/common) 194 | -------------------------------------------------------------------------------- /src/CommonModules/РаботаСКоллекцией/Module.bsl: -------------------------------------------------------------------------------- 1 | // Создает таблицу значений на основании информации о колонках. 2 | // 3 | // Параметры: 4 | // Колонки - Структура - {Имя, ОписаниеТипа}|{Имя, ТипЗнч(Значение)} 5 | // - КоллекцияКолонокТаблицыЗначений, КоллекцияКолонокДереваЗначений, КоллекцияКолонокРезультатаЗапроса 6 | // - Строка 7 | // 8 | // Возвращаемое значение: 9 | // ТаблицаЗначений - Таблица значений 10 | Функция ТаблицаЗначений(Колонки) Экспорт 11 | Таблица = Новый ТаблицаЗначений; 12 | СоздатьКолонки(Таблица, Колонки); 13 | Возврат Таблица; 14 | КонецФункции 15 | 16 | Функция ДеревоЗначений(Колонки) Экспорт 17 | Дерево = Новый ДеревоЗначений; 18 | СоздатьКолонки(Дерево, Колонки); 19 | Возврат Дерево; 20 | КонецФункции 21 | 22 | // Определяет идентификатор строки коллекции значений. Для коллекций, отображаемых в интерфейсе возвращается идентификатор, для 23 | // объектных коллекций - индекс. Разделение нужно для того, чтобы была возможность идентификации строки в интерфейсе 24 | // 25 | // Параметры: 26 | // Коллекция - ДанныеФормыДерево, ДанныеФормыКоллекция, ТабличнаяЧасть, ТаблицаЗначений, КоллекцияСтрокДереваЗначений 27 | // СтрокаКоллекции - ДанныеФормыЭлементКоллекции, ДанныеФормыЭлементДерева, СтрокаТабличнойЧасти, СтрокаТаблицыЗначений, СтрокаДереваЗначений 28 | // 29 | // Возвращаемое значение: 30 | // Число - идентификатор для интерфейсного элемента и индекс для объектного 31 | // 32 | Функция ПолучитьИдентификатор(Коллекция, СтрокаКоллекции) Экспорт 33 | ТипЗначения = ТипЗнч(СтрокаКоллекции); 34 | Если ТипЗначения = Тип("ДанныеФормыЭлементКоллекции") ИЛИ ТипЗначения = Тип("ДанныеФормыЭлементДерева") Тогда 35 | Возврат СтрокаКоллекции.ПолучитьИдентификатор(); 36 | Иначе//СтрокаТабличнойЧасти, СтрокаТаблицыЗначений, СтрокаДереваЗначений 37 | Возврат Коллекция.Индекс(СтрокаКоллекции); 38 | КонецЕсли; 39 | КонецФункции 40 | 41 | // Вычисляет элемент коллекции по идентификатору. Если коллекция это таблица значений, то идентификатор - это индекс, для данных формы - поиск по идентификатору 42 | // 43 | // Параметры: 44 | // Коллекция - ДанныеФормыКоллекция, ДанныеФормыКоллекцияЭлементовДерева, ТаблицаЗначений, КоллекцияСтрокДереваЗначений - 45 | // Идентификатор - Число - индекс строки или идентификатор данных формы 46 | // 47 | Функция НайтиПоИдентификатору(Коллекция, Идентификатор) Экспорт 48 | ТипЗначения = ТипЗнч(Коллекция); 49 | Если ТипЗначения = Тип("ДанныеФормыКоллекция") ИЛИ ТипЗначения = Тип("ДанныеФормыКоллекцияЭлементовДерева") Тогда 50 | Возврат Коллекция.НайтиПоИдентификатору(Идентификатор); 51 | Иначе//СтрокаТабличнойЧасти, СтрокаТаблицыЗначений, СтрокаДереваЗначений 52 | Возврат Коллекция[Идентификатор]; 53 | КонецЕсли; 54 | КонецФункции 55 | 56 | // Одноименная функция СкопироватьКолонки(). При копировании удаляет тип Null 57 | // 58 | // Параметры: 59 | // Источник - ТаблицаЗначений 60 | // КолонкиДобавить - Строка, Массив - имена колонок источника, которые нужно добавить 61 | // КолонкиИсключить - Строка, Массив - имена колонок источника, которые нужно пропустить 62 | // 63 | Функция СкопироватьКолонки(Источник, КолонкиДобавить = "", КолонкиИсключить = "") Экспорт 64 | Таблица = Новый ТаблицаЗначений; 65 | Возврат ДобавитьКолонки(Таблица, Источник, КолонкиДобавить, КолонкиИсключить); 66 | КонецФункции 67 | 68 | // Добавляет колонки, которых нет в изначальной таблице из источника 69 | // 70 | // Параметры: 71 | // Таблица - ТаблицаЗначений 72 | // Источник - ТаблицаЗначений 73 | // КолонкиДобавить - Строка, Массив - имена колонок источника, которые нужно добавить 74 | // КолонкиИсключить - Строка, Массив - имена колонок источника, которые нужно пропустить 75 | // 76 | Функция ДобавитьКолонки(Таблица, Источник, КолонкиДобавить = "", КолонкиИсключить = "") Экспорт 77 | мКолонкиДобавить = ОбщийКлиентСервер.Массив(КолонкиДобавить); 78 | мКолонкиИсключить = ОбщийКлиентСервер.Массив(КолонкиИсключить); 79 | Колонки = Таблица.Колонки; 80 | Для каждого Колонка Из Источник.Колонки Цикл 81 | ИмяКолонки = Колонка.Имя; 82 | Если Колонки.Найти(ИмяКолонки) <> Неопределено 83 | ИЛИ ЗначениеЗаполнено(КолонкиДобавить) И мКолонкиДобавить.Найти(ИмяКолонки) = Неопределено 84 | ИЛИ ЗначениеЗаполнено(КолонкиИсключить) И мКолонкиИсключить.Найти(ИмяКолонки) <> Неопределено Тогда 85 | Продолжить; 86 | КонецЕсли; 87 | ОписаниеКолонки = Новый Структура("Имя,ТипЗначения,Ширина,Заголовок"); 88 | ЗаполнитьЗначенияСвойств(ОписаниеКолонки, Колонка); 89 | ОписаниеКолонки.ТипЗначения = Новый ОписаниеТипов(Колонка.ТипЗначения,, "Null"); 90 | Колонки.Добавить(ОписаниеКолонки.Имя, ОписаниеКолонки.ТипЗначения, ОписаниеКолонки.Заголовок, ОписаниеКолонки.Ширина); 91 | КонецЦикла; 92 | Возврат Таблица; 93 | КонецФункции 94 | 95 | Процедура СоздатьКолонки(Коллекция, Колонки) 96 | ТипЗначения = ТипЗнч(Колонки); 97 | Если ТипЗначения = Тип("Строка") Тогда 98 | Для каждого Колонка Из ОбщийКлиентСервер.Массив(Колонки) Цикл 99 | Коллекция.Колонки.Добавить(Колонка); 100 | КонецЦикла; 101 | ИначеЕсли ТипЗначения = Тип("Массив") Тогда 102 | Если Тип(Колонки[0]) = Тип("Структура") Тогда 103 | Для каждого Колонка Из Колонки Цикл 104 | Коллекция.Колонки.Добавить(Колонка.Имя, Общий.ТипЗначенияИзСтроки(Колонка.ТипЗначения)); 105 | КонецЦикла; 106 | Иначе 107 | Для каждого Колонка Из ОбщийКлиентСервер.Массив(Колонки) Цикл 108 | Коллекция.Колонки.Добавить(Колонка); 109 | КонецЦикла; 110 | КонецЕсли; 111 | ИначеЕсли ТипЗначения = Тип("Структура") Тогда 112 | Для каждого Колонка Из Колонки Цикл 113 | ИмяКолонки = Колонка.Ключ; 114 | Значение = Колонка.Значение; 115 | Если Значение = Неопределено Тогда 116 | Коллекция.Колонки.Добавить(Колонка.Ключ); 117 | Иначе 118 | ТипЗначения = Колонка.Значение; 119 | Если ТипЗнч(ТипЗначения) = Тип("Строка") Тогда 120 | ТипЗначения = Общий.ТипЗначенияИзСтроки(ТипЗначения); 121 | ИначеЕсли ТипЗнч(ТипЗначения) <> Тип("ОписаниеТипов") Тогда 122 | ТипЗначения = Новый ОписаниеТипов(ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(ТипЗнч(ТипЗначения))); 123 | КонецЕсли; 124 | Коллекция.Колонки.Добавить(Колонка.Ключ, ТипЗначения); 125 | КонецЕсли; 126 | КонецЦикла; 127 | ИначеЕсли ТипЗнч(Колонки) = Тип("КоллекцияОбъектовМетаданных") Тогда 128 | Для каждого Колонка Из Колонки Цикл 129 | Коллекция.Колонки.Добавить(Колонка.Имя, Колонка.Тип); 130 | КонецЦикла; 131 | Иначе 132 | Для каждого Колонка Из Колонки Цикл 133 | ТипЗначения = Новый ОписаниеТипов(Колонка.ТипЗначения,, "Null"); 134 | Коллекция.Колонки.Добавить(Колонка.Имя, ТипЗначения); 135 | КонецЦикла; 136 | КонецЕсли; 137 | КонецПроцедуры 138 | 139 | Функция ТаблицаЗначенийВСтруктуру(Таблица, ПривестиСсылкуКСтроке = Ложь) Экспорт 140 | СтруктураТаблицы = Новый Структура("Тип, Колонки, Строки", "ТаблицаЗначений", Новый Массив, Новый Массив); 141 | Колонки = СтруктураТаблицы.Колонки; 142 | Для Каждого Колонка Из Таблица.Колонки Цикл 143 | Колонки.Добавить(Новый Структура("Имя, ТипЗначения", Колонка.Имя, Общий.СтроковоеПредставлениеТипа(Колонка.ТипЗначения))); 144 | КонецЦикла; 145 | Строки = СтруктураТаблицы.Строки; 146 | Для Каждого Строка Из Таблица Цикл 147 | Значения = Новый Массив; 148 | Для Каждого Колонка Из Колонки Цикл 149 | Значение = Строка[Колонка.Имя]; 150 | ТипЗначения = ТипЗнч(Значение); 151 | Если ПривестиСсылкуКСтроке И НЕ Общий.ЭтоПростойТип(ТипЗначения) Тогда 152 | Если ТипЗначения = Тип("УникальныйИдентификатор") Тогда 153 | Значения.Добавить(Строка(Значение)); 154 | Иначе 155 | Значения.Добавить(XMLСтрока(Значение)); 156 | КонецЕсли; 157 | Иначе 158 | Значения.Добавить(Значение); 159 | КонецЕсли; 160 | КонецЦикла; 161 | Строки.Добавить(Значения); 162 | КонецЦикла; 163 | Возврат СтруктураТаблицы; 164 | КонецФункции 165 | 166 | Функция СтруктураВТаблицуЗначений(ТаблицаJSON, НайтиСсылкуИзСтроки = Ложь) Экспорт 167 | ТипСтрока = Тип("Строка"); 168 | Если ТипЗнч(ТаблицаJSON) = ТипСтрока Тогда 169 | Возврат СтруктураВТаблицуЗначений(ОбщийКлиентСервер.JSONВОбъект(ТаблицаJSON), НайтиСсылкуИзСтроки); 170 | КонецЕсли; 171 | Таблица = ТаблицаЗначений(ТаблицаJSON.Колонки); 172 | Колонки = Таблица.Колонки; 173 | Для Каждого ДанныеСтроки Из ТаблицаJSON.Строки Цикл 174 | Строка = Таблица.Добавить(); 175 | Для ИндексКолонки = 0 По ДанныеСтроки.ВГраница() Цикл 176 | ТипЗначения = Колонки[ИндексКолонки].ТипЗначения; 177 | Значение = ДанныеСтроки[ИндексКолонки]; 178 | Если ЗначениеЗаполнено(Значение) И ТипЗнч(Значение) = ТипСтрока Тогда 179 | Если ТипЗначения.СодержитТип(Тип("Дата")) Тогда 180 | Строка[ИндексКолонки] = ?(ЗначениеЗаполнено(Значение), ПрочитатьДатуJSON(ДанныеСтроки[ИндексКолонки], ФорматДатыJSON.ISO), '00010101'); 181 | Продолжить; 182 | КонецЕсли; 183 | Тип = ?(ЗначениеЗаполнено(ТипЗначения.Типы()), ТипЗначения.Типы()[0], Неопределено); 184 | Если НайтиСсылкуИзСтроки И ЗначениеЗаполнено(Тип) Тогда 185 | Если ОбщегоНазначения.ЭтоСсылка(Тип) Тогда 186 | Если Общий.ЭтоТипПеречисления(Тип) Тогда 187 | ИмяПеречисления = Метаданные.НайтиПоТипу(ТипЗначения.Типы()[0]).Имя; 188 | Значение = Перечисления[ИмяПеречисления][Значение]; 189 | Иначе 190 | Значение = ОбщегоНазначения.МенеджерОбъектаПоСсылке(Новый(ТипЗначения.Типы()[0])).ПолучитьСсылку(Новый УникальныйИдентификатор(ДанныеСтроки[ИндексКолонки])); 191 | КонецЕсли; 192 | ИначеЕсли Тип = Тип("УникальныйИдентификатор") Тогда 193 | Значение = Новый УникальныйИдентификатор(Значение); 194 | КонецЕсли; 195 | КонецЕсли; 196 | КонецЕсли; 197 | Строка[ИндексКолонки] = Значение; 198 | КонецЦикла; 199 | КонецЦикла; 200 | Возврат Таблица; 201 | КонецФункции 202 | 203 | Функция ДеревоЗначенийВСтруктуру(Дерево, ПривестиСоставныеТипыКСтроке = Ложь) Экспорт 204 | СтруктураТаблицы = Новый Структура("Тип, Колонки, Строки", "ДеревоЗначений", Новый Массив, Новый Массив); 205 | Колонки = СтруктураТаблицы.Колонки; 206 | Для Каждого Колонка Из Дерево.Колонки Цикл 207 | Колонки.Добавить(Новый Структура("Имя, ТипЗначения", Колонка.Имя, Общий.СтроковоеПредставлениеТипа(Колонка.ТипЗначения))); 208 | КонецЦикла; 209 | ДобавитьСтрокиТаблицы(Колонки, СтруктураТаблицы.Строки, Дерево.Строки, ПривестиСоставныеТипыКСтроке); 210 | Возврат СтруктураТаблицы; 211 | КонецФункции 212 | 213 | Процедура ЗагрузитьСтрокиДерева(Колонки, СтрокиДерева, Строки, НайтиСсылку) 214 | Для Каждого ЭлементСтроки Из Строки Цикл 215 | ДанныеСтроки = ЭлементСтроки.Значения; 216 | Строка = СтрокиДерева.Добавить(); 217 | Для ИндексКолонки = 0 По ДанныеСтроки.ВГраница() Цикл 218 | ТипЗначения = Колонки[ИндексКолонки].ТипЗначения; 219 | Значение = ДанныеСтроки[ИндексКолонки]; 220 | Если ЗначениеЗаполнено(Значение) Тогда 221 | Если ТипЗначения.СодержитТип(Тип("Дата")) Тогда 222 | Строка[ИндексКолонки] = ?(ЗначениеЗаполнено(Значение), ПрочитатьДатуJSON(ДанныеСтроки[ИндексКолонки], ФорматДатыJSON.ISO), '00010101'); 223 | Продолжить; 224 | КонецЕсли; 225 | Если НайтиСсылку И ЗначениеЗаполнено(ТипЗначения.Типы()) И ОбщегоНазначения.ЭтоСсылка(ТипЗначения.Типы()[0]) Тогда 226 | Значение = ОбщегоНазначения.МенеджерОбъектаПоСсылке(Новый(ТипЗначения.Типы()[0])).ПолучитьСсылку(Новый УникальныйИдентификатор(ДанныеСтроки[ИндексКолонки])); 227 | Строка[ИндексКолонки] = Значение; 228 | Продолжить; 229 | КонецЕсли; 230 | КонецЕсли; 231 | Строка[ИндексКолонки] = Значение; 232 | КонецЦикла; 233 | ЗагрузитьСтрокиДерева(Колонки, Строка.Строки, ЭлементСтроки.Строки, НайтиСсылку); 234 | КонецЦикла; 235 | КонецПроцедуры 236 | 237 | Функция СтруктураВДеревоЗначений(ДеревоJSON, НайтиСсылку = Ложь) Экспорт 238 | Если ТипЗнч(ДеревоJSON) = Тип("Строка") Тогда 239 | Возврат СтруктураВДеревоЗначений(ОбщийКлиентСервер.JSONВОбъект(ДеревоJSON), НайтиСсылку); 240 | КонецЕсли; 241 | Дерево = ДеревоЗначений(ДеревоJSON.Колонки); 242 | Колонки = Дерево.Колонки; 243 | ЗагрузитьСтрокиДерева(Колонки, Дерево.Строки, ДеревоJSON.Строки, НайтиСсылку); 244 | Возврат Дерево; 245 | КонецФункции 246 | 247 | Процедура ДобавитьСтрокиТаблицы(Колонки, Строки, СтрокиДерева, ПривестиСоставныеТипыКСтроке) 248 | Для Каждого СтрокаДерева Из СтрокиДерева Цикл 249 | Значения = Новый Массив; 250 | Для Каждого Колонка Из Колонки Цикл 251 | Значение = СтрокаДерева[Колонка.Имя]; 252 | Если ПривестиСоставныеТипыКСтроке И НЕ ОбщегоНазначения.ЭтоСсылка(ТипЗнч(Значение)) Тогда 253 | Значения.Добавить(XMLСтрока(Значение)); 254 | Иначе 255 | Значения.Добавить(Значение); 256 | КонецЕсли; 257 | КонецЦикла; 258 | ПодчиненныеСтроки = Новый Массив; 259 | ДобавитьСтрокиТаблицы(Колонки, ПодчиненныеСтроки, СтрокаДерева.Строки, ПривестиСоставныеТипыКСтроке); 260 | Строки.Добавить(Новый Структура("Значения, Строки", Значения, ПодчиненныеСтроки)); 261 | КонецЦикла; 262 | КонецПроцедуры 263 | 264 | Процедура ЗаполнитьИдентификаторыСтрокДерева(Строки, КолонкаИД, КолонкаИДРодителя, Счетчик) 265 | Для Каждого Строка Из Строки Цикл 266 | Счетчик = Счетчик + 1; 267 | Строка[КолонкаИД] = Счетчик; 268 | Если Строка.Родитель <> Неопределено Тогда 269 | Строка[КолонкаИДРодителя] = Строка.Родитель[КолонкаИД]; 270 | КонецЕсли; 271 | ЗаполнитьИдентификаторыСтрокДерева(Строка.Строки, КолонкаИД, КолонкаИДРодителя, Счетчик); 272 | КонецЦикла; 273 | КонецПроцедуры 274 | 275 | Процедура ДобавитьКолонкиИерархии(Дерево, КолонкаИД = "Идентификатор", КолонкаИДРодителя = "ИдентификаторРодителя") Экспорт 276 | Колонки = Дерево.Колонки; 277 | Если Колонки.Найти(КолонкаИД) = Неопределено Тогда 278 | Колонки.Добавить(КолонкаИД, ОбщегоНазначения.ОписаниеТипаЧисло(9)); 279 | КонецЕсли; 280 | Если Колонки.Найти(КолонкаИДРодителя) = Неопределено Тогда 281 | Колонки.Добавить(КолонкаИДРодителя, ОбщегоНазначения.ОписаниеТипаЧисло(9)); 282 | КонецЕсли; 283 | Счетчик = 0; 284 | ЗаполнитьИдентификаторыСтрокДерева(Дерево.Строки, КолонкаИД, КолонкаИДРодителя, Счетчик); 285 | КонецПроцедуры 286 | 287 | Процедура ДобавитьСтрокиДереваВТаблицуЗначений(Таблица, Строки) 288 | Для Каждого Строка Из Строки Цикл 289 | ЗаполнитьЗначенияСвойств(Таблица.Добавить(), Строка); 290 | ДобавитьСтрокиДереваВТаблицуЗначений(Таблица, Строка.Строки); 291 | КонецЦикла; 292 | КонецПроцедуры 293 | 294 | Функция ДеревоВТаблицуЗначений(Дерево) Экспорт 295 | Таблица = ТаблицаЗначений(Дерево.Колонки); 296 | ДобавитьСтрокиДереваВТаблицуЗначений(Таблица, Дерево.Строки); 297 | Возврат Таблица; 298 | КонецФункции 299 | 300 | Функция ЭлементСтрокиДерева(КолонкаИД, КолонкаИДРодителя) 301 | ЭлементСтроки = Новый Структура("Строка, Родитель"); 302 | ЭлементСтроки.Вставить(КолонкаИД); 303 | ЭлементСтроки.Вставить(КолонкаИДРодителя); 304 | ЭлементСтроки.Вставить("Строки", Новый Массив); 305 | Возврат ЭлементСтроки; 306 | КонецФункции 307 | 308 | Функция ПолучитьЭлементСтрокиДерева(СловарьСтрок, СловарьЭлементовСтрок, Строка, КолонкаИД, КолонкаИДРодителя) 309 | ИД = Строка[КолонкаИД]; 310 | ЭлементСтрокиДерева = СловарьЭлементовСтрок[ИД]; 311 | Если ЗначениеЗаполнено(ЭлементСтрокиДерева) Тогда 312 | Возврат ЭлементСтрокиДерева; 313 | КонецЕсли; 314 | СтрокаДерева = ЭлементСтрокиДерева(КолонкаИД, КолонкаИДРодителя); 315 | СтрокаДерева.Строка = Строка; 316 | СловарьЭлементовСтрок[ИД] = СтрокаДерева; 317 | ИДРодителя = Строка[КолонкаИДРодителя]; 318 | Если ЗначениеЗаполнено(ИДРодителя) Тогда 319 | ЭлементРодителя = ПолучитьЭлементСтрокиДерева(СловарьСтрок, СловарьЭлементовСтрок, СловарьСтрок[ИДРодителя], КолонкаИД, КолонкаИДРодителя); 320 | ЭлементРодителя.Строки.Добавить(СтрокаДерева); 321 | СтрокаДерева.Родитель = ЭлементРодителя; 322 | КонецЕсли; 323 | Возврат СтрокаДерева; 324 | КонецФункции 325 | 326 | Процедура ДобавитьЭлементыСтрокДерева(Строки, ЭлементыСтрокДереваВерхнегоУровня) 327 | Для Каждого ЭлементСтрокиДерева Из ЭлементыСтрокДереваВерхнегоУровня Цикл 328 | Строка = Строки.Добавить(); 329 | ЗаполнитьЗначенияСвойств(Строка, ЭлементСтрокиДерева.Строка); 330 | ДобавитьЭлементыСтрокДерева(Строка.Строки, ЭлементСтрокиДерева.Строки); 331 | КонецЦикла; 332 | КонецПроцедуры 333 | 334 | Функция ТаблицаВДеревоЗначений(Таблица, КолонкаИД = "Идентификатор", КолонкаИДРодителя = "ИдентификаторРодителя") Экспорт 335 | Дерево = ДеревоЗначений(Таблица.Колонки); 336 | // Подготовка словаря 337 | СловарьСтрок = Новый Соответствие; 338 | Для Каждого Строка Из Таблица Цикл 339 | СловарьСтрок[Строка[КолонкаИД]] = Строка; 340 | КонецЦикла; 341 | // Создание иерархической структуры строк 342 | ЭлементыСтрокДереваВерхнегоУровня = Новый Массив; 343 | СловарьЭлементовСтрок = Новый Соответствие; 344 | Для Каждого Строка Из Таблица Цикл 345 | ЭлементСтрокиДерева = ПолучитьЭлементСтрокиДерева(СловарьСтрок, СловарьЭлементовСтрок, Строка, КолонкаИД, КолонкаИДРодителя); 346 | Если ЭлементСтрокиДерева.Родитель = Неопределено Тогда 347 | ЭлементыСтрокДереваВерхнегоУровня.Добавить(ЭлементСтрокиДерева); 348 | КонецЕсли; 349 | КонецЦикла; 350 | // Создание дерева по иерархической структуре строк 351 | ДобавитьЭлементыСтрокДерева(Дерево.Строки, ЭлементыСтрокДереваВерхнегоУровня); 352 | Возврат Дерево; 353 | КонецФункции 354 | 355 | Функция ТаблицаКлючей(ТаблицаИсточника, ПоляКлюча) Экспорт 356 | Ключи = ТаблицаЗначений(ПоляКлюча); 357 | Для Каждого Ключ Из ТаблицаИсточника Цикл 358 | ЗаполнитьЗначенияСвойств(Ключи.Добавить(), Ключ); 359 | КонецЦикла; 360 | Ключи.Свернуть(ПоляКлюча); 361 | Ключи.Сортировать(ПоляКлюча, Новый СравнениеЗначений); 362 | Возврат Ключи; 363 | КонецФункции 364 | 365 | // Добавляет к таблице приемнику строки таблицы источника. Результат сворачивается в разрезе полей приемника по полю ресурса 366 | Процедура ДобавитьТаблицу(ТаблицаПриемник, ТаблицаИсточник, ПоляКлюча, ПоляРесурсов, Знак = "") Экспорт 367 | Если Знак = "-" Тогда 368 | Для Каждого СтрокаИсточника Из ТаблицаИсточник Цикл 369 | НоваяСтрока = ТаблицаПриемник.Добавить(); 370 | ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточника); 371 | ОбщийКлиентСервер.ИнвертироватьЗнак(НоваяСтрока, ПоляРесурсов); 372 | КонецЦикла; 373 | Иначе 374 | Для Каждого СтрокаИсточника Из ТаблицаИсточник Цикл 375 | ЗаполнитьЗначенияСвойств(ТаблицаПриемник.Добавить(), СтрокаИсточника); 376 | КонецЦикла; 377 | КонецЕсли; 378 | ТаблицаПриемник.Свернуть(ПоляКлюча, ПоляРесурсов); 379 | КонецПроцедуры 380 | 381 | Функция ПеречислениеВТаблицуЗначений(ИмяПеречисления) Экспорт 382 | _Перечисление = Перечисления[ИмяПеречисления]; 383 | _Метаданные = Метаданные.Перечисления[ИмяПеречисления]; 384 | Таблица = РаботаСКоллекцией.ТаблицаЗначений(Новый Структура("Ссылка, Имя, Синоним", 385 | Новый ОписаниеТипов("ПеречислениеСсылка." + ИмяПеречисления), 386 | ОбщегоНазначения.ОписаниеТипаСтрока(50), 387 | ОбщегоНазначения.ОписаниеТипаСтрока(50) 388 | ) 389 | ); 390 | Для Каждого ЭлементЗначения Из _Метаданные.ЗначенияПеречисления Цикл 391 | Строка = Таблица.Добавить(); 392 | Строка.Ссылка = _Перечисление[ЭлементЗначения.Имя]; 393 | Строка.Имя = ЭлементЗначения.Имя; 394 | Строка.Синоним = ЭлементЗначения.Синоним; 395 | КонецЦикла; 396 | Возврат Таблица; 397 | КонецФункции 398 | 399 | Процедура СкопироватьКолонкуРекурсивно(Дерево, КолонкаИсточник, КолонкаПолучатель) Экспорт 400 | Строки = Дерево.Строки; 401 | Строки.ЗагрузитьКолонку(Строки.ВыгрузитьКолонку(КолонкаИсточник), КолонкаПолучатель); 402 | Для Каждого Строка Из Строки Цикл 403 | СкопироватьКолонкуРекурсивно(Строка, КолонкаИсточник, КолонкаПолучатель) 404 | КонецЦикла; 405 | КонецПроцедуры 406 | 407 | Функция КоллекцияЗначенийВСтруктуру(КоллекцияЗначений, ПривестиСоставныеТипыКСтроке = Ложь) Экспорт 408 | Если ТипЗнч(КоллекцияЗначений) = Тип("ДеревоЗначений") Тогда 409 | Возврат ДеревоЗначенийВСтруктуру(КоллекцияЗначений, ПривестиСоставныеТипыКСтроке); 410 | ИначеЕсли ТипЗнч(КоллекцияЗначений) = Тип("ТаблицаЗначений") Тогда 411 | Возврат ТаблицаЗначенийВСтруктуру(КоллекцияЗначений, ПривестиСоставныеТипыКСтроке); 412 | Иначе 413 | ВызватьИсключение "Неизвестный тип коллекции " + ТипЗнч(КоллекцияЗначений); 414 | КонецЕсли; 415 | КонецФункции 416 | 417 | Функция ВывестиВТабличныйДокумент(Коллекция, ТабличныйДокумент = Неопределено) Экспорт 418 | Если ТабличныйДокумент = Неопределено Тогда 419 | ТабличныйДокумент = Новый ТабличныйДокумент; 420 | КонецЕсли; 421 | МодельСхемыКомпоновки = Общий.МодельСхемыКомпоновкиДанных(Коллекция); 422 | //////////////////////////////////////////////////////////////////////////////// 423 | // Настройка компоновки 424 | МодельНастройкиКомпоновки = Общий.МодельНастройкиКомпоновкиДанных(МодельСхемыКомпоновки.НастройкиПоУмолчанию()) 425 | ; 426 | Для Каждого Колонка Из Коллекция.Колонки Цикл 427 | МодельНастройкиКомпоновки 428 | .Поле(Колонка.Имя) 429 | ; 430 | КонецЦикла; 431 | // Описание структуры 432 | МодельНастройкиКомпоновки 433 | .Структура() 434 | .ГруппировкаНачать() 435 | .ПолеГруппировки("*") 436 | .Поле("*") 437 | .ГруппировкаЗавершить() 438 | ; 439 | // Компоновка 440 | МодельМакетаКомпоновки = Общий.МодельМакетаКомпоновкиДанных() 441 | .Схема(МодельСхемыКомпоновки.СхемаКомпоновкиДанных) 442 | .Настройки(МодельНастройкиКомпоновки.Настройки) 443 | .Скомпоновать() 444 | .ВнешниеНаборыДанных(МодельСхемыКомпоновки.ВнешниеНаборыДанных) 445 | ; 446 | // Вывод 447 | Возврат МодельМакетаКомпоновки.Вывести(ТабличныйДокумент); 448 | КонецФункции 449 | 450 | Функция ВJSON(Коллекция) Экспорт 451 | ТипЗначения = ТипЗнч(Коллекция); 452 | Если ТипЗначения = Тип("ТаблицаЗначений") Тогда 453 | Возврат ОбщийКлиентСервер.ОбъектВJSON(ТаблицаЗначенийВСтруктуру(Коллекция)); 454 | ИначеЕсли ТипЗначения = Тип("ДеревоЗначений") Тогда 455 | Возврат ОбщийКлиентСервер.ОбъектВJSON(ДеревоЗначенийВСтруктуру(Коллекция)); 456 | ИначеЕсли ТипЗначения = Тип("Структура") И Коллекция.Свойство("Тип") Тогда 457 | Возврат ОбщийКлиентСервер.ОбъектВJSON(Коллекция); 458 | Иначе 459 | ВызватьИсключение "Неизвестный тип коллекции " + ТипЗначения; 460 | КонецЕсли; 461 | КонецФункции 462 | 463 | Функция ИзJSON(КоллекцияJSON) Экспорт 464 | Перем ТипЗначения; 465 | Коллекция = ОбщийКлиентСервер.JSONВОбъект(КоллекцияJSON); 466 | Коллекция.Свойство("Тип", ТипЗначения); 467 | Если НЕ ЗначениеЗаполнено(ТипЗначения) ИЛИ ТипЗначения = "ТаблицаЗначений" Тогда 468 | Возврат СтруктураВТаблицуЗначений(Коллекция); 469 | ИначеЕсли ТипЗначения = "ДеревоЗначений" Тогда 470 | Возврат СтруктураВДеревоЗначений(Коллекция); 471 | Иначе 472 | ВызватьИсключение "Неизвестный тип коллекции " + ТипЗначения; 473 | КонецЕсли; 474 | КонецФункции 475 | 476 | Функция ВCSV(Таблица, Знач Разделитель = "Таб") Экспорт 477 | Строки = Новый Массив; 478 | Разделитель = Символы[Разделитель]; 479 | Колонки = Новый Массив; 480 | Для Каждого Колонка Из Таблица.Колонки Цикл 481 | Колонки.Добавить(Колонка.Имя); 482 | КонецЦикла; 483 | Строки.Добавить(СтрСоединить(Колонки, Разделитель)); 484 | Значения = Новый Массив; 485 | Для Каждого СтрокаТаблицы Из Таблица Цикл 486 | Для Каждого ИмяКолонки Из Колонки Цикл 487 | Значение = СтрокаТаблицы[ИмяКолонки]; 488 | ТипЗначения = ТипЗнч(Значение); 489 | Если ТипЗначения = Тип("Строка") Тогда 490 | Значения.Добавить("""" + Значение + """"); 491 | Иначе 492 | Значения.Добавить(Строка(Значение)); 493 | КонецЕсли; 494 | КонецЦикла; 495 | Строки.Добавить(СтрСоединить(Значения, Разделитель)); 496 | КонецЦикла; 497 | КонецФункции 498 | 499 | Функция CSVвСтруктуру(Текст, Знач Разделитель = "Таб") Экспорт 500 | Разделитель = Символы[Разделитель]; 501 | СтруктураТаблицы = Новый Структура("Тип, Колонки, Строки", "ТаблицаЗначений", Новый Массив, Новый Массив); 502 | Строки = СтрРазделить(Текст, Символы.ПС); 503 | Шапка = РаботаСМассивом.Сдвинуть(Строки); 504 | СтруктураТаблицы.Колонки = РаботаСМассивом.АТДМассив(СтрРазделить(Шапка, Разделитель)) 505 | .Отобразить("СтрРазделить(Элемент, ': ', Ложь)") 506 | .Отобразить("Структура('Имя, ТипЗначения', Элемент[0], ?(Элемент.Количество() = 2, Элемент[1], Неопределено))") 507 | ; 508 | СтруктураТаблицы.Строки = РаботаСМассивом.Отобразить(Строки, "СтрРазделить(Элемент, Контекст)", Разделитель); 509 | Возврат СтруктураТаблицы; 510 | КонецФункции 511 | 512 | Функция MarkdownВСтруктуру(Текст) Экспорт 513 | Строки = СтрРазделить(Текст, Символы.ПС); 514 | Колонки = РаботаСМассивом.АТДМассив(СтрРазделить(Строки[0], "| ", Ложь)) 515 | .Отобразить("СтрРазделить(Элемент, ': ', Ложь)") 516 | .Отобразить("Структура('Имя, ТипЗначения', Элемент[0], ?(Элемент.Количество() = 2, Элемент[1], Неопределено))") 517 | ; 518 | КонецФункции 519 | 520 | Функция ВMarkdown(Коллекция) Экспорт 521 | Если ТипЗнч(Коллекция) = Тип("ТаблицаЗначений") Тогда 522 | Возврат ВMarkdown(ТаблицаЗначенийВСтруктуру(Коллекция)); 523 | КонецЕсли; 524 | Колонки = РаботаСМассивом.Отобразить(Коллекция.Колонки, "СтрШаблон(Элемент.Имя, Элемент)"); 525 | Строки = Новый Массив; 526 | Строки.Добавить("|" + СтрСоединить(Колонки, "|") + "|"); 527 | Строки.Добавить(СтроковыеФункцииКлиентСервер.СформироватьСтрокуСимволов("|-", Колонки.Количество()) + "|"); 528 | Для Каждого Значения Из Коллекция.Строки Цикл 529 | Строки.Добавить("|" + СтрСоединить(Значения, "|") + "|"); 530 | КонецЦикла; 531 | Возврат СтрСоединить(Строки, Символы.ПС); 532 | КонецФункции 533 | 534 | Процедура ДополнитьТаблицу(ТаблицаПриемник, ТаблицаИсточник) Экспорт 535 | Для Каждого СтрокаИсточника Из ТаблицаИсточник Цикл 536 | ЗаполнитьЗначенияСвойств(ТаблицаПриемник.Добавить(), СтрокаИсточника); 537 | КонецЦикла; 538 | КонецПроцедуры 539 | 540 | -------------------------------------------------------------------------------- /src/CommonModules/РаботаСМассивом/Module.bsl: -------------------------------------------------------------------------------- 1 | // Подсистема "Абстрактный тип данных массив" 2 | // Автор: Калякин Андрей Г. 3 | // https://github.com/KalyakinAG/adt-array 4 | // https://infostart.ru/1c/articles/1473034/ 5 | 6 | //@skip-check server-execution-safe-mode 7 | //@skip-check module-unused-local-variable 8 | #Область ПрограммныйИнтерфейс 9 | 10 | Функция ПривестиСтроку(Строка) 11 | Возврат ?(Лев(Строка, 1) = "!", Прав(Строка, СтрДлина(Строка) - 1), СтрЗаменить(Строка, "'", """")); 12 | КонецФункции 13 | 14 | // find - поиск элемента коллекции 15 | // 16 | // Параметры: 17 | // Элементы - Массив - Коллекция 18 | // ВыражениеПредиката - Строка - Функция, при вычислении которой для искомого элемента возвращается Истина. 19 | // Контекст - Любой - Контекст, который может быть использован для вызова функции 20 | // Параметры - Любой - Параметры, которые могут быть использованы при вычислении функции 21 | // 22 | // Возвращаемое значение: 23 | // Произвольный, Неопределено -- Найденный элемент 24 | // Найденный элемент 25 | Функция НайтиЭлемент(Элементы, ВыражениеПредикатаБезОбработки, Контекст = Неопределено, Параметры = Неопределено) Экспорт 26 | ВыражениеПредиката = ПривестиСтроку(ВыражениеПредикатаБезОбработки); 27 | Для Каждого Элемент Из Элементы Цикл 28 | Если Вычислить(ВыражениеПредиката) Тогда 29 | Возврат Элемент; 30 | КонецЕсли; 31 | КонецЦикла; 32 | Возврат Неопределено; 33 | КонецФункции 34 | 35 | Функция Индекс(Элементы, ВыражениеПредикатаБезОбработки, Контекст = Неопределено, Параметры = Неопределено) Экспорт 36 | ВыражениеПредиката = ПривестиСтроку(ВыражениеПредикатаБезОбработки); 37 | Для Индекс = 0 По Элементы.Количество() - 1 Цикл 38 | Элемент = Элементы[Индекс]; 39 | Если Вычислить(ВыражениеПредиката) Тогда 40 | Возврат Индекс; 41 | КонецЕсли; 42 | КонецЦикла; 43 | Возврат Неопределено; 44 | КонецФункции 45 | 46 | // Найти элемент в очереди с приоритетом. Проверят наличие элемента в очереди с приоритетом 47 | // 48 | // Параметры: 49 | // Очередь - Массив - элементы очереди, по-умолчанию отсортированы от меньшего к большему 50 | // Элемент - Любой - 51 | // ИндексНачала - Число - Индекс начала 52 | // ИндексОкончания - Число - Индекс окончания 53 | // ФункцияСравнения - Строка - Выражение предиката 54 | // 55 | // Возвращаемое значение: 56 | // Булево - Истина - элемент найден 57 | Функция НайтиЭлементОчередиСПриоритетом(Очередь, Элемент, ИндексНачала, ИндексОкончания, ФункцияСравнения, Контекст = Неопределено, Параметры = Неопределено) Экспорт 58 | Если ИндексНачала = ИндексОкончания Тогда 59 | Возврат Ложь; 60 | КонецЕсли; 61 | ИндексСередины = Окр((ИндексНачала + ИндексОкончания) / 2, 0, 0); 62 | Если ИндексСередины = ИндексОкончания Тогда 63 | Возврат Ложь; 64 | КонецЕсли; 65 | А = Очередь[ИндексСередины];//@skip-check module-unused-local-variable 66 | Б = Элемент;//@skip-check module-unused-local-variable 67 | Результат = Вычислить(ФункцияСравнения); 68 | Если Результат = 0 Тогда 69 | Возврат Истина; 70 | ИначеЕсли Результат > 0 Тогда 71 | Возврат НайтиЭлементОчередиСПриоритетом(Очередь, Элемент, ИндексНачала, ИндексСередины, ФункцияСравнения, Контекст, Параметры); 72 | Иначе 73 | Возврат НайтиЭлементОчередиСПриоритетом(Очередь, Элемент, ИндексСередины + 1, ИндексОкончания, ФункцияСравнения, Контекст, Параметры); 74 | КонецЕсли; 75 | КонецФункции 76 | 77 | // filter 78 | // 79 | // Параметры: 80 | // Элементы - Массив - Коллекция 81 | // ВыражениеПредиката - Строка 82 | // Контекст - Неопределено - Контекст 83 | // Параметры - Неопределено - Параметры 84 | // 85 | // Возвращаемое значение: 86 | // Массив - Отобрать 87 | Функция Отобрать(Элементы, ВыражениеПредикатаБезОбработки, Контекст = Неопределено, Параметры = Неопределено) Экспорт 88 | НайденныеЭлементы = Новый Массив; 89 | ВыражениеПредиката = ПривестиСтроку(ВыражениеПредикатаБезОбработки); 90 | Для Каждого Элемент Из Элементы Цикл 91 | Если Вычислить(ВыражениеПредиката) Тогда 92 | НайденныеЭлементы.Добавить(Элемент); 93 | КонецЕсли; 94 | КонецЦикла; 95 | Возврат НайденныеЭлементы; 96 | КонецФункции 97 | 98 | // map 99 | // 100 | // Параметры: 101 | // Элементы - Массив - Коллекция 102 | // Выражение - Строка - Выражение функции 103 | // Контекст - Неопределено - Контекст 104 | // Параметры - Неопределено - Параметры 105 | // 106 | // Возвращаемое значение: 107 | // Массив - Отобразить 108 | Функция Отобразить(Элементы, ВыражениеБезОбработки, Контекст = Неопределено, Параметры = Неопределено) Экспорт 109 | Выражение = ПривестиСтроку(ВыражениеБезОбработки); 110 | НовыеЭлементы = Новый Массив; 111 | Если ТипЗнч(Элементы) = Тип("Массив") Тогда 112 | Для Индекс = 0 По Элементы.ВГраница() Цикл 113 | Элемент = Элементы[Индекс]; 114 | НовыеЭлементы.Добавить(Вычислить(Выражение)); 115 | КонецЦикла; 116 | Иначе 117 | Для Каждого Элемент Из Элементы Цикл 118 | НовыеЭлементы.Добавить(Вычислить(Выражение)); 119 | КонецЦикла; 120 | КонецЕсли; 121 | Возврат НовыеЭлементы; 122 | КонецФункции 123 | 124 | // flat 125 | Функция Спрямить(Элементы, Глубина = Неопределено) Экспорт 126 | СледующаяГлубина = ?(Глубина = Неопределено, Неопределено, Глубина - 1); 127 | НовыеЭлементы = Новый Массив; 128 | Для Каждого Элемент Из Элементы Цикл 129 | Если ТипЗнч(Элемент) = Тип("Массив") И (СледующаяГлубина = Неопределено ИЛИ СледующаяГлубина >= 0) Тогда 130 | ДополнитьМассив(НовыеЭлементы, Спрямить(Элемент, СледующаяГлубина)); 131 | Продолжить; 132 | КонецЕсли; 133 | НовыеЭлементы.Добавить(Элемент); 134 | КонецЦикла; 135 | Возврат НовыеЭлементы; 136 | КонецФункции 137 | 138 | // reduce 139 | // 140 | //МаксимальныйУровень = РаботаСМассивом.АТДМассив(ПоказателиРасчета) 141 | // .Отобразить("Макс(Накопитель, Элемент.Уровень)", 0) 142 | //; 143 | // 144 | //// Группировка показателей по уровням 145 | //Показатели = РаботаСМассивом.АТДМассив(ПоказателиРасчета) 146 | // .Отобразить("Элемент.Значение") 147 | // .Преобразовать(" 148 | // |ОбщийКлиентСервер.ВставитьСвойство( 149 | // | Накопитель, 150 | // | Элемент.Уровень, 151 | // | ?(Накопитель[Элемент.Уровень] = Неопределено, 152 | // | ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Элемент), 153 | // | РаботаСМассивом.Дополнить(Накопитель[Элемент.Уровень], ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Элемент)) 154 | // | ) 155 | // |)", Новый Соответствие) 156 | //; 157 | // 158 | //// Пересборка соответствия 159 | //ЭлементыПоказателей = РаботаСМассивом.АТДМассив(Показатели) 160 | // .Преобразовать("ОбщийКлиентСервер.ВставитьСвойство(Накопитель, Элемент.Ключ, РаботаСМассивом.Отобразить(Элемент.Значение, ' ''ЗначенияПоказателей'' + Элемент.Код'))", Новый Соответствие) 161 | //; 162 | // 163 | // Параметры: 164 | // Элементы - Массив - Коллекция 165 | // Выражение - Строка - Выражение функции 166 | // НачальноеЗначение - Неопределено - Начальное значение 167 | // Контекст - Неопределено - Контекст 168 | // Параметры - Неопределено - Параметры 169 | // 170 | // Возвращаемое значение: 171 | // Произвольный - Преобразовать 172 | // 173 | Функция Преобразовать(Элементы, ВыражениеБезОбработки, НачальноеЗначение = Неопределено, Контекст = Неопределено, Параметры = Неопределено) Экспорт 174 | Выражение = ПривестиСтроку(ВыражениеБезОбработки); 175 | Накопитель = НачальноеЗначение; 176 | Для Каждого Элемент Из Элементы Цикл 177 | Накопитель = Вычислить(Выражение); 178 | КонецЦикла; 179 | Возврат Накопитель; 180 | КонецФункции 181 | 182 | // last 183 | Функция Последний(Элементы) Экспорт 184 | ВГраница = Элементы.ВГраница(); 185 | Если ВГраница = -1 Тогда 186 | Возврат Неопределено; 187 | КонецЕсли; 188 | Результат = Элементы[ВГраница]; 189 | Возврат Результат; 190 | КонецФункции 191 | 192 | // pop 193 | Функция Взять(Элементы) Экспорт 194 | ВГраница = Элементы.ВГраница(); 195 | Если ВГраница = -1 Тогда 196 | Возврат Неопределено; 197 | КонецЕсли; 198 | Результат = Элементы[ВГраница]; 199 | Элементы.Удалить(ВГраница); 200 | Возврат Результат; 201 | КонецФункции 202 | 203 | // shift 204 | Функция Сдвинуть(Элементы) Экспорт 205 | ВГраница = Элементы.ВГраница(); 206 | Если ВГраница = -1 Тогда 207 | Возврат Неопределено; 208 | КонецЕсли; 209 | Результат = Элементы[0]; 210 | Элементы.Удалить(0); 211 | Возврат Результат; 212 | КонецФункции 213 | 214 | // push 215 | Функция Положить(Элементы, Элемент) Экспорт 216 | Элементы.Добавить(Элемент); 217 | Возврат Элементы; 218 | КонецФункции 219 | 220 | // add 221 | Функция Добавить(Элементы, Элемент) Экспорт 222 | Элементы.Добавить(Элемент); 223 | Возврат Элементы; 224 | КонецФункции 225 | 226 | // slice 227 | Функция Срез(Элементы, НижняяГраница = 0, Знач ВерхняяГраница = Неопределено, Шаг = 1) Экспорт 228 | Если ВерхняяГраница = Неопределено Тогда 229 | ВерхняяГраница = Элементы.Количество(); 230 | КонецЕсли; 231 | Результат = Новый Массив; 232 | Индекс = НижняяГраница; 233 | Пока Индекс < ВерхняяГраница Цикл 234 | Результат.Добавить(Элементы[Индекс]); 235 | Индекс = Индекс + Шаг; 236 | КонецЦикла; 237 | Возврат Результат; 238 | КонецФункции 239 | 240 | // range 241 | Функция Диапазон(НижняяГраница, ВерхняяГраница, Шаг = 1) Экспорт 242 | Если НижняяГраница >= ВерхняяГраница Тогда 243 | Возврат Новый Массив; 244 | КонецЕсли; 245 | Результат = Новый Массив; 246 | Индекс = НижняяГраница; 247 | Пока Истина Цикл 248 | СледующийИндекс = Индекс + Шаг; 249 | Если СледующийИндекс > ВерхняяГраница Тогда 250 | Прервать; 251 | КонецЕсли; 252 | Результат.Добавить(Индекс); 253 | Индекс = СледующийИндекс; 254 | КонецЦикла; 255 | Возврат Результат; 256 | КонецФункции 257 | 258 | // forEach 259 | Функция ДляКаждого(Элементы, АлгоритмБезОбработки, Контекст = Неопределено, Параметры = Неопределено) Экспорт 260 | Алгоритм = ПривестиСтроку(АлгоритмБезОбработки); 261 | Для Каждого Элемент Из Элементы Цикл 262 | //@skip-check unsupported-operator 263 | Выполнить(Алгоритм); 264 | КонецЦикла; 265 | КонецФункции 266 | 267 | // Следующий. 268 | // 269 | // Параметры: 270 | // Индекс - Число 271 | // Элемент - Неопределено 272 | // Элементы - Массив из Неопределено 273 | // Шаг - Число - Шаг, позволяет выполнять обход по данным заданной ширины 274 | // 275 | // Возвращаемое значение: 276 | // Булево - Следующий 277 | Функция Следующий(Индекс, Элемент, Элементы, Шаг = 1) Экспорт 278 | Если Индекс = Неопределено Тогда 279 | Индекс = 0; 280 | Иначе 281 | Индекс = Индекс + Шаг; 282 | КонецЕсли; 283 | Если Индекс > Элементы.ВГраница() Тогда 284 | Возврат Ложь; 285 | КонецЕсли; 286 | Элемент = Элементы[Индекс]; 287 | Возврат Истина; 288 | КонецФункции 289 | 290 | // Сравнить. 291 | // 292 | // Параметры: 293 | // А - Любой - сравнимаемое значение 1 294 | // Б - Любой - сравнимаемое значение 2 295 | // Направление - Строка - +/- 296 | // 297 | // Возвращаемое значение: 298 | // Число - < 0, сортировка поставит 1-ое значение по меньшему индексу, чем 2-ое, 299 | // = 0, сортировка не меняет индексы значений, 300 | // > 0, сортировка поставит 2-ое значение по меньшему индексу, чем 1-ое 301 | Функция Сравнить(А, Б, Направление = "+") Экспорт 302 | Если А = Б Тогда 303 | Возврат 0; 304 | КонецЕсли; 305 | Результат = ?(А < Б, -1, 1); 306 | Возврат ?(Направление = "-", -Результат, Результат); 307 | КонецФункции 308 | 309 | // Возвращает массив в свойств. Требования к свойствам такие же как при объявлении структуры. 310 | // 311 | // Параметры: 312 | // Значение - Строка - свойства через запятую 313 | // - Массив - возвращается в исходном массиве 314 | // Возвращаемое значение: 315 | // Массив - массив свойств 316 | // 317 | Функция Массив(Значение) Экспорт 318 | ТипЗначения = ТипЗнч(Значение); 319 | Если ТипЗначения = Тип("Массив") Тогда 320 | Возврат Значение; 321 | КонецЕсли; 322 | Если ТипЗначения = Тип("Строка") И НЕ ПустаяСтрока(Значение) Тогда 323 | Возврат СтрРазделить(СтрЗаменить(СтрЗаменить(Значение, " ", ""), Символы.ПС, ""), ",", Ложь); 324 | КонецЕсли; 325 | Возврат Новый Массив; 326 | КонецФункции 327 | 328 | // Параметры: 329 | // Поля - Строка - поля через запятую с указанием направления сортировки +/- 330 | // Возвращаемое значение: 331 | // Массив - {Поле, Направление} 332 | Функция ПоляСравнения(Поля) Экспорт 333 | ПоляСравнения = Новый Массив; 334 | Для Каждого Поле Из Массив(Поля) Цикл 335 | Направление = Прав(Поле, 1); 336 | Если Направление = "+" ИЛИ Направление = "-" Тогда 337 | ПоляСравнения.Добавить(Новый Структура("Поле, Направление", Лев(Поле, СтрДлина(Поле) - 1), Направление)); 338 | Иначе 339 | ПоляСравнения.Добавить(Новый Структура("Поле, Направление", Поле, "+")); 340 | КонецЕсли; 341 | КонецЦикла; 342 | Возврат ПоляСравнения; 343 | КонецФункции 344 | 345 | // Сравнивает два структурных объекта. Сравнивается каждое поле отдельно и если они не равны, то сразу определяется порядок. 346 | // Т.е. принцип такой: находится первое неравенство и оно как больший разряд определяет порядок элементов. 347 | Функция СравнитьПо(А, Б, ПоляСравнения) Экспорт 348 | Для Каждого ПолеСравнения Из ПоляСравнения Цикл 349 | Поле = ПолеСравнения.Поле; 350 | Результат = Сравнить(А[Поле], Б[Поле], ПолеСравнения.Направление); 351 | Если Результат <> 0 Тогда 352 | Возврат Результат; 353 | КонецЕсли; 354 | КонецЦикла; 355 | Возврат 0; 356 | КонецФункции 357 | 358 | // sortBy 359 | Процедура СортироватьПо(Элементы, Знач Поля) Экспорт 360 | ПоляСравнения = ПоляСравнения(Поля); 361 | БыстраяСортировкаПо(Элементы, ПоляСравнения, 0, Элементы.ВГраница()); 362 | КонецПроцедуры 363 | 364 | // sort 365 | Процедура Сортировать(Элементы, Знач ФункцияСравненияБезОбработки = Неопределено, Контекст = Неопределено, Параметры = Неопределено) Экспорт 366 | Если НЕ ЗначениеЗаполнено(ФункцияСравненияБезОбработки) ИЛИ ФункцияСравненияБезОбработки = "+" Тогда 367 | Список = Новый СписокЗначений; 368 | Список.ЗагрузитьЗначения(Элементы); 369 | Список.СортироватьПоЗначению(); 370 | Элементы = Список.ВыгрузитьЗначения(); 371 | Возврат; 372 | ИначеЕсли ФункцияСравненияБезОбработки = "-" Тогда 373 | Список = Новый СписокЗначений; 374 | Список.ЗагрузитьЗначения(Элементы); 375 | Список.СортироватьПоЗначению(НаправлениеСортировки.Убыв); 376 | Элементы = Список.ВыгрузитьЗначения(); 377 | Возврат; 378 | КонецЕсли; 379 | ФункцияСравнения = ПривестиСтроку(ФункцияСравненияБезОбработки); 380 | БыстраяСортировка(Элементы, ФункцияСравнения, Контекст, Параметры, 0, Элементы.ВГраница()); 381 | КонецПроцедуры 382 | 383 | Процедура СортироватьЭлементыКоллекции(ЭлементыКоллекции, Знач ФункцияСравненияБезОбработки = Неопределено, СортироватьВложенные = Истина) Экспорт 384 | Если ЗначениеЗаполнено(ФункцияСравненияБезОбработки) Тогда 385 | ФункцияСравнения = ПривестиСтроку(ФункцияСравненияБезОбработки); 386 | Иначе 387 | ФункцияСравнения = "Сравнить(А.Наименование, Б.Наименование)"; 388 | КонецЕсли; 389 | Если ЭлементыКоллекции.Количество() = 0 Тогда 390 | Возврат; 391 | КонецЕсли; 392 | Если СортироватьВложенные Тогда 393 | Для Каждого ЭлементДерева Из ЭлементыКоллекции Цикл 394 | СортироватьЭлементыКоллекции(ЭлементДерева.ПолучитьЭлементы(), ФункцияСравнения, СортироватьВложенные); 395 | КонецЦикла; 396 | КонецЕсли; 397 | СортироватьЭлементы(ЭлементыКоллекции, ФункцияСравнения, 0, ЭлементыКоллекции.Количество() - 1); 398 | КонецПроцедуры 399 | 400 | // Выполняет пропорциональное распределение суммы в соответствии 401 | // с заданными коэффициентами распределения. 402 | // Используется рекурсивный алгоритм с уменьшением базы. Допускается использование только положительных чисел. 403 | // Подробное описание алгоритма в [Распределение суммы по базе](https://infostart.ru/1c/articles/416217/) 404 | // Алгоритм в сравнении с другими в [Честное распределение суммы](https://infostart.ru/1c/tools/16630/) (вариант 3) 405 | // 406 | // Параметры: 407 | // РаспределяемаяСумма - Число - сумма, которую надо распределить. Сумма должна соответствовать определенной точности. 408 | // Коэффициенты - Массив - коэффициенты распределения 409 | // Точность - Число - точность округления при распределении. Необязателен. 410 | // 411 | // Возвращаемое значение: 412 | // Массив - массив размерностью равный массиву коэффициентов, содержит 413 | // суммы в соответствии с весом коэффициента (из массива коэффициентов). 414 | // В случае, если распределить невозможно (кол-во коэффициентов = 0 415 | // есть коэффициенты с отрицательным значением или суммарный вес коэффициентов = 0), 416 | // тогда будет возвращено Неопределено. 417 | // 418 | // Пример: 419 | // 420 | // Коэффициенты = Новый Массив; 421 | // Коэффициенты.Добавить(1); 422 | // Коэффициенты.Добавить(2); 423 | // Результат = РаспределитьСумму(1, Коэффициенты); 424 | // // Результат = [0.33, 0.67] 425 | // 426 | Функция РаспределитьСумму(Знач РаспределяемаяСумма, Знач Коэффициенты, Знач Точность = 2) Экспорт 427 | Если Коэффициенты.Количество() = 0 ИЛИ РаспределяемаяСумма = 0 Тогда 428 | Возврат Неопределено; 429 | КонецЕсли; 430 | НужноИнвертироватьРезультат = Ложь; 431 | Если РаспределяемаяСумма < 0 Тогда 432 | РаспределяемаяСумма = -РаспределяемаяСумма; 433 | НужноИнвертироватьРезультат = Истина; 434 | КонецЕсли; 435 | КоэффициентыОтрицательны = (Коэффициенты[0] < 0); 436 | КоэффициентыРаспределения = Новый Массив(Новый ФиксированныйМассив(Коэффициенты)); // Копируем массив в памяти. 437 | СуммаКоэффициентов = 0; 438 | Для Индекс = 0 По КоэффициентыРаспределения.Количество() - 1 Цикл 439 | Коэффициент = КоэффициентыРаспределения[Индекс]; 440 | Если КоэффициентыОтрицательны Тогда 441 | Если Коэффициент > 0 Тогда 442 | Возврат Неопределено; 443 | КонецЕсли; 444 | Иначе 445 | Если Коэффициент < 0 Тогда 446 | Возврат Неопределено; 447 | КонецЕсли; 448 | КонецЕсли; 449 | СуммаКоэффициентов = СуммаКоэффициентов + Коэффициент; 450 | КонецЦикла; 451 | 452 | Если СуммаКоэффициентов = 0 Тогда 453 | Возврат Неопределено; 454 | КонецЕсли; 455 | 456 | Результат = Новый Массив(КоэффициентыРаспределения.Количество()); 457 | 458 | ОстатокРаспределения = РаспределяемаяСумма; 459 | 460 | Для Индекс = 0 По КоэффициентыРаспределения.Количество() - 1 Цикл 461 | Если ОстатокРаспределения = 0 Тогда 462 | Результат[Индекс] = 0; 463 | Продолжить; 464 | КонецЕсли; 465 | Коэффициент = КоэффициентыРаспределения[Индекс]; 466 | СуммаРаспределения = Мин(ОстатокРаспределения, Окр(ОстатокРаспределения * Коэффициент / СуммаКоэффициентов, Точность, 1)); 467 | Результат[Индекс] = СуммаРаспределения; 468 | СуммаКоэффициентов = СуммаКоэффициентов - Коэффициент; 469 | ОстатокРаспределения = ОстатокРаспределения - СуммаРаспределения; 470 | КонецЦикла; 471 | 472 | Если ОстатокРаспределения <> 0 Тогда 473 | ВызватьИсключение "Не удалось распределить сумму"; 474 | КонецЕсли; 475 | 476 | Если НужноИнвертироватьРезультат Тогда 477 | Для Индекс = 0 По Результат.ВГраница() Цикл 478 | Результат[Индекс] = -Результат[Индекс]; 479 | КонецЦикла; 480 | КонецЕсли; 481 | Возврат Результат; 482 | КонецФункции 483 | 484 | // Дополняет массив МассивПриемник значениями из массива МассивИсточник. 485 | // 486 | // Параметры: 487 | // МассивПриемник - Массив - массив, в который необходимо добавить значения. 488 | // МассивИсточник - Массив - массив значений для заполнения. 489 | // ТолькоУникальныеЗначения - Булево - если истина, то в массив будут включены только уникальные значения. 490 | // НижняяГраница - Число - нижняя граница среза 491 | // ВерхняяГраница - Число - верхняя граница среза 492 | // Шаг - Число - ширина обхода источника 493 | // 494 | Функция Дополнить(МассивПриемник, МассивИсточник, ТолькоУникальныеЗначения = Ложь, НижняяГраница = 0, Знач ВерхняяГраница = Неопределено, Шаг = 1) Экспорт 495 | Если ВерхняяГраница = Неопределено Тогда 496 | ВерхняяГраница = МассивИсточник.Количество(); 497 | КонецЕсли; 498 | Индекс = НижняяГраница; 499 | Если ТолькоУникальныеЗначения Тогда 500 | УникальныеЗначения = Новый Соответствие; 501 | Для Каждого Значение Из МассивПриемник Цикл 502 | УникальныеЗначения.Вставить(Значение, Истина); 503 | КонецЦикла; 504 | Пока Индекс < ВерхняяГраница Цикл 505 | Значение = МассивИсточник[Индекс]; 506 | Если УникальныеЗначения[Значение] = Неопределено Тогда 507 | МассивПриемник.Добавить(Значение); 508 | УникальныеЗначения.Вставить(Значение, Истина); 509 | КонецЕсли; 510 | Индекс = Индекс + Шаг; 511 | КонецЦикла; 512 | Иначе 513 | Пока Индекс < ВерхняяГраница Цикл 514 | МассивПриемник.Добавить(МассивИсточник[Индекс]); 515 | Индекс = Индекс + Шаг; 516 | КонецЦикла; 517 | КонецЕсли; 518 | Возврат МассивПриемник; 519 | КонецФункции 520 | 521 | // Возвращает разность массивов. Разностью двух массивов является массив, содержащий 522 | // все элементы первого массива, не существующие во втором массиве. 523 | // 524 | // Параметры: 525 | // Массив - Массив - массив элементов, из которого необходимо выполнить вычитание; 526 | // МассивВычитания - Массив - массив элементов, который будет вычитаться. 527 | // 528 | // Возвращаемое значение: 529 | // Массив - разностью двух массивов. 530 | // 531 | // Пример: 532 | // //А = [1, 3, 5, 7]; 533 | // //В = [3, 7, 9]; 534 | // Результат = ОбщегоНазначенияКлиентСервер.РазностьМассивов(А, В); 535 | // //Результат = [1, 5]; 536 | // 537 | Функция Разность(Знач Массив, Знач МассивВычитания) Экспорт 538 | 539 | Результат = Новый Массив; 540 | Для Каждого Элемент Из Массив Цикл 541 | Если МассивВычитания.Найти(Элемент) = Неопределено Тогда 542 | Результат.Добавить(Элемент); 543 | КонецЕсли; 544 | КонецЦикла; 545 | Возврат Результат; 546 | 547 | КонецФункции 548 | 549 | // Дополняет массив МассивПриемник значениями из массива МассивИсточник. 550 | // 551 | // Параметры: 552 | // МассивПриемник - Массив - массив, в который необходимо добавить значения. 553 | // МассивИсточник - Массив - массив значений для заполнения. 554 | // ТолькоУникальныеЗначения - Булево - если истина, то в массив будут включены только уникальные значения. 555 | // 556 | Процедура ДополнитьМассив(МассивПриемник, МассивИсточник, ТолькоУникальныеЗначения = Ложь) Экспорт 557 | Дополнить(МассивПриемник, МассивИсточник, ТолькоУникальныеЗначения); 558 | КонецПроцедуры 559 | 560 | Функция Свернуть(Знач Массив) Экспорт 561 | Возврат Дополнить(Новый Массив, Массив, Истина); 562 | КонецФункции 563 | 564 | Функция Скопировать(МассивИсточник) Экспорт 565 | МассивРезультат = Новый Массив; 566 | Для Каждого Элемент Из МассивИсточник Цикл 567 | МассивРезультат.Добавить(Элемент); 568 | КонецЦикла; 569 | Возврат МассивРезультат; 570 | КонецФункции 571 | 572 | Функция СкопироватьМассив(МассивИсточник) Экспорт 573 | Возврат Скопировать(МассивИсточник); 574 | КонецФункции 575 | 576 | Функция АТДМассив(Элементы = Неопределено) Экспорт 577 | #Если Клиент Тогда 578 | АТДМассив = ПолучитьФорму("Обработка.АТДМассив.Форма.Форма"); 579 | #Иначе 580 | АТДМассив = Обработки.АТДМассив.Создать(); 581 | #КонецЕсли 582 | Если Элементы <> Неопределено Тогда 583 | АТДМассив.Установить(Элементы); 584 | КонецЕсли; 585 | Возврат АТДМассив; 586 | КонецФункции 587 | 588 | // Положить в очередь с приоритетом. 589 | // 590 | // Параметры: 591 | // Очередь - Массив - элемнты очереди, по-умолчанию отсортированы от меньшего к большему 592 | // Элемент - Любой - 593 | // ФункцияСравнения - Строка - Выражение предиката 594 | Процедура ПоложитьВОчередьСПриоритетом(Очередь, Элемент, ФункцияСравнения = "Сравнить(А, Б)", Контекст = Неопределено, Параметры = Неопределено) Экспорт 595 | ИндексЭлемента = НайтиИндексЭлементаОчередиСПриоритетом(Очередь, Элемент, 0, Очередь.Количество(), ФункцияСравнения, Контекст, Параметры); 596 | Очередь.Вставить(ИндексЭлемента, Элемент); 597 | КонецПроцедуры 598 | 599 | 600 | // Порядок определяется алгоритмом рекурсивного спуска по вершинам графа. Чем выше порядок, тем выше вершина 601 | // 4 - 11 - 12 - 13 602 | // | | \ / 603 | // 3 7 10 604 | // | | | \ 605 | // 2 6 8 9 606 | // | | 607 | // 1 5 608 | // Параметры: 609 | // Элементы - Массив 610 | // Ключ - Строка - имя свойства, которое определяет уникальность элемента. Используется для вывода пути к узлу элемента и для поиска подчиненных элементов, где хранятся только ключи 611 | // СвойствоПорядка - Строка - имя свойства, по которому определяется порядок. Тип свойства числовое 612 | // СвойствоПодчиненныхЭлементов - Строка - имя свойство, в котором хранится список подчиненных элементов 613 | // Словарь - Соответствие - используется для поиска элемента по ключу, если подчиненные элементы содержат только ключи 614 | // СвойствоЗначенияСловара - Строка - используется для доступа к подчиненному элементу, если по ключу из словаря элемент содержится в свойстве 615 | // 616 | // Если в процессе определения порядка обнаруживается циклическая ссылка, то выкидывается исключение с выводом цепочки зависимостей 617 | // 618 | Функция ОпределитьТопографическийПорядок(Элементы, Ключ = "Идентификатор", СвойствоПодчиненныхЭлементов = "ПодчиненныеЭлементы", СвойствоПорядка = "Порядок", Словарь = Неопределено, СвойствоЗначенияСловара = Неопределено) Экспорт 619 | ТипКоллекции = ТипЗнч(Элементы); 620 | ЭтоКлючЗначение = (ТипКоллекции = Тип("Соответствие") ИЛИ ТипКоллекции = Тип("Структура")); 621 | Если НЕ ЗначениеЗаполнено(Словарь) Тогда 622 | Словарь = Новый Соответствие; 623 | Для Каждого ЭлементИлиКлючЗначение Из Элементы Цикл 624 | Если ЭтоКлючЗначение Тогда 625 | Элемент = ЭлементИлиКлючЗначение.Значение; 626 | Иначе 627 | Элемент = ЭлементИлиКлючЗначение; 628 | КонецЕсли; 629 | Словарь[Элемент[Ключ]] = Элемент; 630 | Элемент[СвойствоПорядка] = -1; 631 | КонецЦикла; 632 | Иначе 633 | Для Каждого ЭлементИлиКлючЗначение Из Элементы Цикл 634 | Если ЭтоКлючЗначение Тогда 635 | Элемент = ЭлементИлиКлючЗначение.Значение; 636 | ИначеЕсли ТипЗнч(ЭлементИлиКлючЗначение) = Тип("Строка") Тогда 637 | Если ЗначениеЗаполнено(СвойствоЗначенияСловара) Тогда 638 | Элемент = Словарь[ЭлементИлиКлючЗначение][СвойствоЗначенияСловара]; 639 | Иначе 640 | Элемент = Словарь[ЭлементИлиКлючЗначение]; 641 | КонецЕсли; 642 | Иначе 643 | Элемент = ЭлементИлиКлючЗначение; 644 | КонецЕсли; 645 | Элемент[СвойствоПорядка] = -1; 646 | КонецЦикла; 647 | КонецЕсли; 648 | Возврат ОпределитьПорядок(Элементы, СвойствоПорядка, СвойствоПодчиненныхЭлементов, РаботаСОчередью.ОчередьУникальныхЗначений(Ключ), Словарь, СвойствоЗначенияСловара) 649 | КонецФункции 650 | 651 | Функция Содержит(Элементы, Значение) Экспорт 652 | Возврат Элементы.Найти(Значение) <> Неопределено; 653 | КонецФункции 654 | 655 | #КонецОбласти 656 | 657 | //@skip-check server-execution-safe-mode 658 | //@skip-check module-unused-local-variable 659 | #Область СлужебныеПроцедурыИФункции 660 | 661 | // Топографическая сортировка 662 | Функция ОпределитьПорядок(Элементы, СвойствоПорядка, СвойствоПодчиненныхЭлементов, Очередь, Словарь, СвойствоЗначенияСловара, Знач Порядок = 0) 663 | ТипКоллекции = ТипЗнч(Элементы); 664 | ЭтоКлючЗначение = (ТипКоллекции = Тип("Соответствие") ИЛИ ТипКоллекции = Тип("Структура")); 665 | Для Каждого ЭлементИлиКлючЗначение Из Элементы Цикл 666 | // Нужно проверить тип элемента. Если это подчиненные элементы, то это ключ, верхнего - это сами элементы 667 | Если ЭтоКлючЗначение Тогда 668 | Элемент = ЭлементИлиКлючЗначение.Значение; 669 | ИначеЕсли ТипЗнч(ЭлементИлиКлючЗначение) = Тип("Строка") Тогда 670 | Если ЗначениеЗаполнено(СвойствоЗначенияСловара) Тогда 671 | Элемент = Словарь[ЭлементИлиКлючЗначение][СвойствоЗначенияСловара]; 672 | Иначе 673 | Элемент = Словарь[ЭлементИлиКлючЗначение]; 674 | КонецЕсли; 675 | Иначе 676 | Элемент = ЭлементИлиКлючЗначение; 677 | КонецЕсли; 678 | ПорядокЭлемента = Элемент[СвойствоПорядка]; 679 | Если ПорядокЭлемента <> -1 Тогда 680 | Порядок = Макс(Порядок, ПорядокЭлемента); 681 | Продолжить; 682 | КонецЕсли; 683 | // Контроль циклической ссылки 684 | Если РаботаСОчередью.Содержит(Очередь, Элемент) Тогда 685 | ЭлементыСтека = РаботаСМассивом.Отобразить(Очередь.Элементы, СтрШаблон("Элемент['%1']", Очередь.Ключ)); 686 | ЭлементыСтека.Добавить(Элемент[Очередь.Ключ]); 687 | ВызватьИсключение "Циклическая ссылка: " + СтрСоединить(ЭлементыСтека, "<--"); 688 | КонецЕсли; 689 | // Контроль циклической ссылки 690 | РаботаСОчередью.Положить(Очередь, Элемент); 691 | // Рекурсивный спуск 692 | Порядок = ОпределитьПорядок(Элемент[СвойствоПодчиненныхЭлементов], СвойствоПорядка, СвойствоПодчиненныхЭлементов, Очередь, Словарь, СвойствоЗначенияСловара, Порядок); 693 | // Контроль циклической ссылки 694 | РаботаСОчередью.Взять(Очередь); 695 | // Порядок 696 | Порядок = Порядок + 1; 697 | Элемент[СвойствоПорядка] = Порядок; 698 | КонецЦикла; 699 | Возврат Порядок; 700 | КонецФункции 701 | 702 | // Быстрая сортировка 703 | // http://ru.wikibooks.org/wiki/%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B_%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D0%B1%D1%8B%D1%81%D1%82%D1%80%D0%BE%D0%B9_%D1%81%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B8 704 | // Реализация взята из публикации https://infostart.ru/1c/articles/204320/ 705 | // 706 | // Параметры: 707 | // Элементы - Массив 708 | // ФункцияСравнения - Строка, Неопределено - ФункцияСравнения 709 | // Контекст - Неопределено - Контекст 710 | // НижнийПредел - Число - Нижний предел 711 | // ВерхнийПредел - Число - Верхний предел 712 | Процедура БыстраяСортировка(Элементы, ФункцияСравнения, Контекст, Параметры, НижнийПредел, ВерхнийПредел) 713 | Если НЕ ЗначениеЗаполнено(Элементы) Тогда 714 | Возврат; 715 | КонецЕсли; 716 | Начало = НижнийПредел; 717 | Конец = ВерхнийПредел; 718 | Б = Элементы[Цел((Начало + Конец)/2)]; 719 | Пока Истина Цикл 720 | А = Элементы[Начало]; 721 | Пока Вычислить(ФункцияСравнения) < 0 Цикл // Элементы[Начало] < Б 722 | Начало = Начало + 1; 723 | А = Элементы[Начало]; 724 | КонецЦикла; 725 | А = Элементы[Конец]; 726 | Пока Вычислить(ФункцияСравнения) > 0 Цикл // Элементы[Конец] > Б 727 | Конец = Конец - 1; 728 | А = Элементы[Конец]; 729 | КонецЦикла; 730 | Если Начало <= Конец Тогда 731 | Значение = Элементы[Начало]; 732 | Элементы[Начало] = Элементы[Конец]; 733 | Элементы[Конец] = Значение; 734 | Начало = Начало + 1; 735 | Конец = Конец - 1; 736 | КонецЕсли; 737 | Если Начало > Конец Тогда 738 | Прервать; 739 | КонецЕсли; 740 | КонецЦикла; 741 | Если НижнийПредел < Конец Тогда 742 | БыстраяСортировка(Элементы, ФункцияСравнения, Контекст, Параметры, НижнийПредел, Конец); 743 | КонецЕсли; 744 | Если Начало < ВерхнийПредел Тогда 745 | БыстраяСортировка(Элементы, ФункцияСравнения, Контекст, Параметры, Начало, ВерхнийПредел); 746 | КонецЕсли; 747 | КонецПроцедуры 748 | 749 | Процедура БыстраяСортировкаПо(Элементы, ПоляСравнения, НижнийПредел, ВерхнийПредел) Экспорт 750 | Если НЕ ЗначениеЗаполнено(Элементы) Тогда 751 | Возврат; 752 | КонецЕсли; 753 | Начало = НижнийПредел; 754 | Конец = ВерхнийПредел; 755 | Б = Элементы[Цел((Начало + Конец)/2)]; 756 | Пока Истина Цикл 757 | А = Элементы[Начало]; 758 | Пока СравнитьПо(А, Б, ПоляСравнения) < 0 Цикл // Элементы[Начало] < Б 759 | Начало = Начало + 1; 760 | А = Элементы[Начало]; 761 | КонецЦикла; 762 | А = Элементы[Конец]; 763 | Пока СравнитьПо(А, Б, ПоляСравнения) > 0 Цикл // Элементы[Конец] > Б 764 | Конец = Конец - 1; 765 | А = Элементы[Конец]; 766 | КонецЦикла; 767 | Если Начало <= Конец Тогда 768 | Значение = Элементы[Начало]; 769 | Элементы[Начало] = Элементы[Конец]; 770 | Элементы[Конец] = Значение; 771 | Начало = Начало + 1; 772 | Конец = Конец - 1; 773 | КонецЕсли; 774 | Если Начало > Конец Тогда 775 | Прервать; 776 | КонецЕсли; 777 | КонецЦикла; 778 | Если НижнийПредел < Конец Тогда 779 | БыстраяСортировкаПо(Элементы, ПоляСравнения, НижнийПредел, Конец); 780 | КонецЕсли; 781 | Если Начало < ВерхнийПредел Тогда 782 | БыстраяСортировкаПо(Элементы, ПоляСравнения, Начало, ВерхнийПредел); 783 | КонецЕсли; 784 | КонецПроцедуры 785 | 786 | // Найти индекс элемента очереди с приоритетом. 787 | // 788 | // Параметры: 789 | // Очередь - Массив - элементы очереди, по-умолчанию отсортированы от меньшего к большему 790 | // Элемент - Любой - 791 | // ИндексНачала - Число - Индекс начала 792 | // ИндексОкончания - Число - Индекс окончания 793 | // ФункцияСравнения - Строка - Выражение предиката 794 | // 795 | // Возвращаемое значение: 796 | // Число - Найти индекс элемента очереди с приоритетом 797 | Функция НайтиИндексЭлементаОчередиСПриоритетом(Очередь, Элемент, ИндексНачала, ИндексОкончания, ФункцияСравнения, Контекст = Неопределено, Параметры = Неопределено) 798 | Если ИндексНачала = ИндексОкончания Тогда 799 | Возврат ИндексНачала; 800 | КонецЕсли; 801 | ИндексСередины = Окр((ИндексНачала + ИндексОкончания) / 2, 0, 0); 802 | Если ИндексСередины = ИндексОкончания Тогда 803 | Возврат ИндексОкончания; 804 | КонецЕсли; 805 | А = Очередь[ИндексСередины];//@skip-check module-unused-local-variable 806 | Б = Элемент;//@skip-check module-unused-local-variable 807 | Если Вычислить(ФункцияСравнения) > 0 Тогда 808 | Возврат НайтиИндексЭлементаОчередиСПриоритетом(Очередь, Элемент, ИндексНачала, ИндексСередины, ФункцияСравнения, Контекст, Параметры); 809 | Иначе 810 | Возврат НайтиИндексЭлементаОчередиСПриоритетом(Очередь, Элемент, ИндексСередины + 1, ИндексОкончания, ФункцияСравнения, Контекст, Параметры); 811 | КонецЕсли; 812 | КонецФункции 813 | 814 | Процедура СортироватьЭлементы(Элементы, ВыражениеПредиката, НижнийПредел, ВерхнийПредел) 815 | Начало = НижнийПредел; 816 | Конец = ВерхнийПредел; 817 | Б = Элементы[Цел((Начало + Конец)/2)]; 818 | Пока Истина Цикл 819 | А = Элементы[Начало]; 820 | Пока Вычислить(ВыражениеПредиката) < 0 Цикл // Элементы[Начало] < Б 821 | Начало = Начало + 1; 822 | А = Элементы[Начало]; 823 | КонецЦикла; 824 | А = Элементы[Конец]; 825 | Пока Вычислить(ВыражениеПредиката) > 0 Цикл // Элементы[Конец] > Б 826 | Конец = Конец - 1; 827 | А = Элементы[Конец]; 828 | КонецЦикла; 829 | Если Начало <= Конец Тогда 830 | // Дерево значений 831 | // Начало -> Конец 832 | // Конец -> Начало 833 | ШагСдвига = Конец - Начало; 834 | Если НЕ ШагСдвига = 0 Тогда 835 | Элементы.Сдвинуть(Начало, ШагСдвига); 836 | ШагСдвига = ШагСдвига - 1; 837 | Если НЕ ШагСдвига = 0 Тогда 838 | Элементы.Сдвинуть(Конец - 1, -ШагСдвига); 839 | КонецЕсли; 840 | КонецЕсли; 841 | // Дерево значений 842 | Начало = Начало + 1; 843 | Конец = Конец - 1; 844 | КонецЕсли; 845 | Если Начало > Конец Тогда 846 | Прервать; 847 | КонецЕсли; 848 | КонецЦикла; 849 | Если НижнийПредел < Конец Тогда 850 | СортироватьЭлементы(Элементы, ВыражениеПредиката, НижнийПредел, Конец); 851 | КонецЕсли; 852 | Если Начало < ВерхнийПредел Тогда 853 | СортироватьЭлементы(Элементы, ВыражениеПредиката, Начало, ВерхнийПредел); 854 | КонецЕсли; 855 | КонецПроцедуры 856 | 857 | Функция ОтобразитьСвойстваЭлементов(Элементы, Свойства) Экспорт 858 | СловарьОтображения = ОбщийКлиентСервер.СловарьОтображенияСвойств(Свойства); 859 | НовыеЭлементы = Новый Массив; 860 | Для Каждого Элемент Из Элементы Цикл 861 | НовыеЭлементы.Добавить(ОбщийКлиентСервер.ОтобразитьСвойства(Элемент, СловарьОтображения)); 862 | КонецЦикла; 863 | Возврат НовыеЭлементы; 864 | КонецФункции 865 | 866 | #КонецОбласти --------------------------------------------------------------------------------