Свернуть значения таблицы, массива, строки

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

  • СвернутьСтроку(Стр, СтрНачальныйРазделитель, СтрИтоговыйРазделитель) – Убирает повторяющиеся в строке значения. Значения разделены между собой указанным разделителем. Также можно поменять этот разделитель после преобразования.
  • СвернутьМассив(пМассив) – Убирает повторяющиеся в массиве значения.
  • СвернутьТаблицу(Таб, ИсключаяПоля, ПоляСуммы, СуммироватьВсеЧисла) – Убирает повторяющиеся значения в таблице. Процедура аналогична методу ТаблицаЗначений.Свернуть(КолонкиГруппировок, КолонкиСуммирования).

Реализация функций в 1С следующая:

1. Функция «Свернуть строку».

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
// Сворачивает в строке используемые повторяющиеся значения.
//
// Параметры:
//	Стр - <Строка> - Исходная строка;
//	СтрНачальныйРазделитель - <Строка> - Разделитель для разбора строки, по умолчанию ",";
//	СтрИтоговыйРазделитель - <Строка> - Разделитель, используемый в собранной строке. 
//	 По умолчанию ",".
//
// Возвращаемое значение:
//	<Строка> - Собранная строка.
//
Функция СвернутьСтроку(Стр, СтрНачальныйРазделитель = ",", СтрИтоговыйРазделитель = ", ") Экспорт
 
	Результат = "";
	МассивСтр = РазобратьСтрокуВМассивПоРазделителю(Стр, СтрНачальныйРазделитель);
	ЗаполненныйМассив = Новый Массив;
	Для Каждого Элемент Из МассивСтр Цикл
		Если ЗаполненныйМассив.Найти(Элемент) = Неопределено Тогда 
			ЗаполненныйМассив.Добавить(Элемент);
			Результат = Результат + СтрИтоговыйРазделитель + Элемент;
		КонецЕсли;
	КонецЦикла;
	Результат = Сред(Результат, СтрДлина(СтрИтоговыйРазделитель)+1);
 
	Возврат Результат;	
КонецФункции;

 

2. Функция «Свернуть массив».

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
// Сворачивает в массиве повторяющиеся значения.
//
// Параметры:
//	пМассив - <Массив> - Исходный массив.
//
// Возвращаемое значение:
//	<Массив> - Свёрнутый массив.
//
Функция СвернутьМассив(пМассив) Экспорт
 
	Если пМассив.Количество() > 1 Тогда
		ТЗ = Новый ТаблицаЗначений;
		ИмяКолонки = "Колонка1";
		ТЗ.Колонки.Добавить(ИмяКолонки);
		Для Индекс = 0 По пМассив.Количество()-1 Цикл
			ТЗ.Добавить();
		КонецЦикла;
		ТЗ.ЗагрузитьКолонку(пМассив, ИмяКолонки);
		ТЗ.Свернуть(ИмяКолонки, "");
 
		Возврат ТЗ.ВыгрузитьКолонку(ИмяКолонки);
	Иначе
		Результат = Новый Массив;
		Для Каждого Элемент Из пМассив Цикл
			Результат.Добавить(Элемент);
		КонецЦикла;
		Возврат Результат;
	КонецЕсли;
 
КонецФункции;

 

3. Процедура «Свернуть таблицу». Отличается от процедуры по умолчанию тем, что сворачивает все поля за исключением указанных и имеет дополнительную возможность распознавать колонки с числами.

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
// Сворачивает в таблице повторяющиеся значения.
//
// Параметры:
//	Таб - <ТаблицаЗначений> - Исходная таблица;
//	ИсключаяПоля - <Строка> - Колонки таблицы, исключаемые из рассмотрения;
//	ПоляСуммы - <Строка> - Поля для суммирования строк;
//	СуммироватьВсеЧисла - <Булево> - Команда на суммирование всех колонок с числами (поля добавляются к полям суммы).
//
Процедура СвернутьТаблицу(Таб, ИсключаяПоля = "НомерСтроки", ПоляСуммы = "", СуммироватьВсеЧисла = Ложь) Экспорт
 
	МассивИсключаяПоля = ?(ИсключаяПоля = "", Новый Массив, ПреобразоватьВМассив(ИсключаяПоля));
	Если СуммироватьВсеЧисла Тогда
		МассивПоляСуммы = Новый Массив;
		Для Каждого Колонка Из Таб.Колонки Цикл
			МассивТипов = Колонка.ТипЗначения.Типы();
			Если 
			 МассивТипов.Найти(Тип("Число")) <> Неопределено
			 И (МассивТипов.Количество() = 1 
			 ИЛИ (МассивТипов.Количество() = 2 И (МассивТипов.Найти(Тип("Null")) <> Неопределено ИЛИ МассивТипов.Найти(Тип("Неопределено")) <> Неопределено))
			 ИЛИ (МассивТипов.Количество() = 3 И МассивТипов.Найти(Тип("Null")) <> Неопределено И МассивТипов.Найти(Тип("Неопределено")) <> Неопределено))
			Тогда
				ПоляСуммы = ?(ПустаяСтрока(ПоляСуммы), "", ПоляСуммы + ", ") + Колонка.Имя;
				МассивПоляСуммы.Добавить(Колонка.Имя);
			КонецЕсли;
		КонецЦикла;
	Иначе
		МассивПоляСуммы = ?(ПоляСуммы = "", Новый Массив, ПреобразоватьВМассив(ПоляСуммы));
	КонецЕсли;
 
	СтрКолонки = "";
	Для Каждого Колонка Из Таб.Колонки Цикл
		Если МассивПоляСуммы.Найти(Колонка.Имя) = Неопределено И МассивИсключаяПоля.Найти(Колонка.Имя) = Неопределено Тогда
			СтрКолонки = СтрКолонки + ", " + Колонка.Имя;
		КонецЕсли;
	КонецЦикла;
	СтрКолонки = Сред(СтрКолонки, 3);
 
	Таб.Свернуть(СтрКолонки, ПоляСуммы);
 
КонецПроцедуры;

 

Также в данном коде используются следующие вспомогательные функции:

  • ПреобразоватьВМассив(Объект, Проверка) – Преобразует объект в массив.
  • РазобратьСтрокуВМассивПоРазделителю(Стр, СтрРазделитель, ИгнорироватьПустые) – Разбирает предложенную строку в массив.

Код вспомогательных функций на 1С:

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
57
58
59
60
61
62
63
// Преобразует в массив переменную любого типа данных.
//
// Параметры:
//	Объект - Произвольный - произвольный объект данных;
//	Проверка - <Булево> - Осуществление проверки на заполненное значение.
//
// Возвращаемое значение:
//	<Массив> - Массив с теми же данными.
//
Функция ПреобразоватьВМассив(Объект, Проверка = Ложь) Экспорт
 
	ОбъектМассив = Новый Массив;
 
	Если НЕ Проверка ИЛИ ЗначениеЗаполнено(Объект) Тогда
		Если ТипЗнч(Объект) = Тип("Массив") Тогда
			ОбъектМассив = Объект;
		ИначеЕсли ТипЗнч(Объект) = Тип("СписокЗначений") Тогда
			ОбъектМассив = Объект.ВыгрузитьЗначения();
		ИначеЕсли ТипЗнч(Объект) = Тип("Строка") Тогда
			ОбъектМассив = РазобратьСтрокуВМассивПоРазделителю(Объект);
		ИначеЕсли ТипЗнч(Объект) = Тип("Структура") Тогда
			Для Каждого Элемент Из Объект Цикл
				ОбъектМассив.Добавить(Элемент.Значение);
			КонецЦикла;
		Иначе
			ОбъектМассив.Добавить(Объект);
		КонецЕсли;
	КонецЕсли;
 
	Возврат ОбъектМассив;
КонецФункции;
 
// Разбирает строку в массив подстрок по разделителю. 
// При этом пробелы между подстроками не учитываются.
//
// Параметры:
//	Стр - исходная строка;
//	СтрРазделитель - разделитель, по умолчанию ",";
//	ИгнорироватьПустые - игнорировать ли пустые места между разделителями.
//
// Возвращаемое значение:
//	Массив строк
//
Функция РазобратьСтрокуВМассивПоРазделителю(Знач Стр, СтрРазделитель = ",", ИгнорироватьПустые = Ложь) Экспорт
 
	Результат = Новый Массив;
 
	ВхождениеРазделителя = Найти(Стр, СтрРазделитель);
	Пока ВхождениеРазделителя <> 0 Цикл
		ЧастьДоРазделителя = СокрЛП(Лев(Стр, ВхождениеРазделителя - 1));
		Если НЕ (ИгнорироватьПустые И ПустаяСтрока(ЧастьДоРазделителя)) Тогда
			Результат.Добавить(ЧастьДоРазделителя);
		КонецЕсли;
		Стр = СокрЛП(Сред(Стр, ВхождениеРазделителя + 1));
		ВхождениеРазделителя = Найти(Стр, СтрРазделитель);
	КонецЦикла;
 
	Если НЕ (ИгнорироватьПустые И ПустаяСтрока(Стр)) Тогда
		Результат.Добавить(СокрЛП(Стр));
	КонецЕсли;
 
	Возврат Результат;	
КонецФункции;

Смело используйте эти и другие функции для реализации своих проектов. Удачи!

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