ТаблицаМакетаКомпоновкиДанных.РасположениеИтоговКолонок

Свойства · ColumnsTotalPlacement

Тип: РасположениеИтоговКомпоновкиДанных. Расположение итогов по колонкам.

Полное описание, параметры и ограничения

ТаблицаМакетаКомпоновкиДанных.РасположениеИтоговКолонок (DataCompositionTemplateTable.ColumnsTotalPlacement)

ТаблицаМакетаКомпоновкиДанных (DataCompositionTemplateTable)

РасположениеИтоговКолонок (ColumnsTotalPlacement)

Доступен, начиная с версии 8.1.

Использование:
Чтение и запись.
Описание:
Тип: РасположениеИтоговКомпоновкиДанных.
Расположение итогов по колонкам.
Доступность:

Сервер, толстый клиент, внешнее соединение.

Использование в версии:

Доступен, начиная с версии 8.1.

Методическая информация

Практические примеры

Макет СКД: перенести итоги матрицы и проверить реальные пересечения

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

Где и как запускать

Полный серверный общий модуль УчебныйМакетТаблицы85 собственной новой базы. Отдельный полный модуль формы Пульт ниже. Не выполнялся в 1С.

Подготовка

  1. Создайте НОВУЮ отдельную файловую учебную базу 8.5.1.1343: имя конфигурации УчебныеМакетыТаблиц85, совместимость НеИспользовать, управляемое приложение. Без рабочих данных, расширений, обменов и подписок с внешними действиями. Здесь 1С не запускалась: runtimeVerifiedScenarios=0.

  2. Общие модули → УчебныйМакетТаблицы85: Сервер=Да, Клиент=Нет, Вызов сервера=Нет, Привилегированный=Нет, Глобальный=Нет. Вставьте полный основной модуль ОДНОГО выбранного урока, включая все функции ниже ВыполнитьПример. Не объединяйте два модуля с одинаковыми именами процедур.

  3. Обработки → УчебныйПросмотрТаблицы85 → управляемая форма Пульт. Создайте команду Выполнить, назначьте одноимённую клиентскую процедуру её действием и добавьте кнопку. Ниже полный отдельный модуль Пульт. F7 и обновление только новой учебной базы; серверный обработчик вызывает общий модуль без передачи Макет или ТабличныйДокумент в клиент.

  4. Каждый запуск заново создаёт свою Local-схему, настройки, макет, процессор и табличный документ в памяти. Нет чтения документов/справочников/регистров, записи БД, файлов, настоящей сети, печати и сохранения пользовательских настроек.

  5. Учебные продажи: Север/Книга 750, Север/Ручка 50, Юг/Книга 500. Во втором уроке у каждой исходной записи свой КодСтроки guide-sale-1/2/3. Подписи магазинов/товаров/кодов должны остаться уникальными на соответствующей оси; проверка намеренно прекращается при неоднозначной подписи.

  6. Поставьте серверную точку останова перед последним Сообщить в ВыполнитьПример; откройте просмотр значений Документ либо ДоПереноса/ПослеПереноса/Восстановленный. Сверьте реальные пересечения и оформление. Статические проверки не подтверждают будущую отрисовку или расчёт в 1С.

Процедура ВыполнитьПример() Экспорт
    ПроверитьСвойКонтекст();
    Схема = Новый СхемаКомпоновкиДанных;
    Источник = Схема.ИсточникиДанных.Добавить();
    Источник.Имя = "УчебныеПродажи";
    Источник.ТипИсточникаДанных = "Local";
    Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
    Набор.Имя = "СвоиТриСтроки";
    Набор.ИсточникДанных = Источник.Имя;
    Набор.АвтоЗаполнениеДоступныхПолей = Истина;
    Набор.Запрос = "ВЫБРАТЬ
    |    ""Север"" КАК Магазин,
    |    ""Книга"" КАК Наименование,
    |    3 КАК Количество,
    |    750 КАК Сумма
    |ОБЪЕДИНИТЬ ВСЕ
    |ВЫБРАТЬ ""Север"", ""Ручка"", 1, 50
    |ОБЪЕДИНИТЬ ВСЕ
    |ВЫБРАТЬ ""Юг"", ""Книга"", 2, 500";
    Для Каждого ИмяРесурса Из СтрРазделить("Сумма,Количество", ",") Цикл
        Ресурс = Схема.ПоляИтога.Добавить();
        Ресурс.ПутьКДанным = ИмяРесурса;
        Ресурс.Выражение = "Сумма(" + ИмяРесурса + ")";
    КонецЦикла;
    Настройки = Схема.НастройкиПоУмолчанию;
    ТаблицаНастроек = Настройки.Структура.Добавить(Тип("ТаблицаКомпоновкиДанных"));
    ТаблицаНастроек.Имя = "УчебныеМагазиныПоТоварам";
    ТаблицаНастроек.Использование = Истина;
    Выбор = ТаблицаНастроек.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
    Выбор.Поле = Новый ПолеКомпоновкиДанных("Сумма");
    Выбор.Использование = Истина;
    СтрокаНастроек = ТаблицаНастроек.Строки.Добавить();
    СтрокаНастроек.Имя = "Магазины";
    СтрокаНастроек.Использование = Истина;
    ПолеМагазина = СтрокаНастроек.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
    ПолеМагазина.Поле = Новый ПолеКомпоновкиДанных("Магазин");
    ПолеМагазина.ТипГруппировки = ТипГруппировкиКомпоновкиДанных.Элементы;
    ПолеМагазина.Использование = Истина;
    КолонкаНастроек = ТаблицаНастроек.Колонки.Добавить();
    КолонкаНастроек.Имя = "Товары";
    КолонкаНастроек.Использование = Истина;
    ПолеТовара = КолонкаНастроек.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
    ПолеТовара.Поле = Новый ПолеКомпоновкиДанных("Наименование");
    ПолеТовара.ТипГруппировки = ТипГруппировкиКомпоновкиДанных.Элементы;
    ПолеТовара.Использование = Истина;
    КонтрольныйЗапрос = Новый Запрос;
    КонтрольныйЗапрос.Текст = Набор.Запрос;
    ИсходныеСтроки = КонтрольныйЗапрос.Выполнить().Выгрузить();
    Если ИсходныеСтроки.Количество() <> 3 Или ИсходныеСтроки.Итог("Сумма") <> 1300 Тогда
        ВызватьИсключение "Изменились собственные учебные данные";
    КонецЕсли;
    Компоновщик = Новый КомпоновщикМакетаКомпоновкиДанных;
    Макет = Компоновщик.Выполнить(Схема, Настройки);
    ТаблицаМакета = НайтиСвоюТаблицу(Макет.Тело);
    Если ТипЗнч(ТаблицаМакета.Имя) <> Тип("Строка") Или ТипЗнч(ТаблицаМакета.Идентификатор) <> Тип("Строка") Тогда
        ВызватьИсключение "Имя и идентификатор настоящей таблицы должны быть строками";
    КонецЕсли;
    Сообщить("Скомпилированная таблица: " + ТаблицаМакета.Имя + "; идентификатор=" + ТаблицаМакета.Идентификатор);
    ПроверитьСсылкуНаОбласть(Макет, ТаблицаМакета.МакетШапки);
    ПроверитьСсылкуНаОбласть(Макет, ТаблицаМакета.МакетИтоговСтрок);
    ПроверитьСсылкуНаОбласть(Макет, ТаблицаМакета.МакетИтоговКолонок);
    ПроверитьСсылкуНаОбласть(Макет, ТаблицаМакета.МакетОбщихИтогов);
    ДоПереноса = СформироватьСвойДокумент(Макет);
    ПроверитьСвоюМатрицу(ДоПереноса);
    ПрежнееРасположениеСтрок = ТаблицаМакета.РасположениеИтоговСтрок;
    ПрежнееРасположениеКолонок = ТаблицаМакета.РасположениеИтоговКолонок;
    Попытка
        ТаблицаМакета.РасположениеИтоговСтрок = РасположениеИтоговКомпоновкиДанных.Начало;
        ТаблицаМакета.РасположениеИтоговКолонок = РасположениеИтоговКомпоновкиДанных.Конец;
        Если ТаблицаМакета.РасположениеИтоговСтрок <> РасположениеИтоговКомпоновкиДанных.Начало
            Или ТаблицаМакета.РасположениеИтоговКолонок <> РасположениеИтоговКомпоновкиДанных.Конец Тогда
            ВызватьИсключение "Нужно изменить только расположение итогов собственного макета";
        КонецЕсли;
        ПослеПереноса = СформироватьСвойДокумент(Макет);
        ПроверитьСвоюМатрицу(ПослеПереноса);
    Исключение
        ТаблицаМакета.РасположениеИтоговСтрок = ПрежнееРасположениеСтрок;
        ТаблицаМакета.РасположениеИтоговКолонок = ПрежнееРасположениеКолонок;
        ВызватьИсключение;
    КонецПопытки;
    ТаблицаМакета.РасположениеИтоговСтрок = ПрежнееРасположениеСтрок;
    ТаблицаМакета.РасположениеИтоговКолонок = ПрежнееРасположениеКолонок;
    Восстановленный = СформироватьСвойДокумент(Макет);
    ПроверитьСвоюМатрицу(Восстановленный);
    Сообщить("Проверены реальные пересечения 750/50/500, отсутствие Юг-Ручка и общий итог 1300 до переноса, после и после восстановления.");
КонецПроцедуры

Функция НайтиСвоюТаблицу(ТелоМакета)
    Найденные = Новый Массив;
    Для Каждого Часть Из ТелоМакета Цикл
        Если ТипЗнч(Часть) = Тип("ТаблицаМакетаКомпоновкиДанных") Тогда
            Найденные.Добавить(Часть);
        КонецЕсли;
    КонецЦикла;
    Если Найденные.Количество() <> 1 Тогда
        ВызватьИсключение "Нужна ровно одна собственная таблица в простом макете";
    КонецЕсли;
    Возврат Найденные.Получить(0);
КонецФункции

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

Функция СформироватьСвойДокумент(СвойМакет)
    Процессор = Новый ПроцессорКомпоновкиДанных;
    Процессор.Инициализировать(СвойМакет);
    Документ = Новый ТабличныйДокумент;
    Вывод = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    Вывод.ОтображатьПроцентВывода = Ложь;
    Вывод.УстановитьДокумент(Документ);
    РезультатВывода = Вывод.Вывести(Процессор, Ложь);
    Если ТипЗнч(РезультатВывода) <> Тип("ТабличныйДокумент") Тогда
        ВызватьИсключение "Не получен собственный табличный документ";
    КонецЕсли;
    Возврат РезультатВывода;
КонецФункции

Процедура ПроверитьМалыйДокумент(Документ)
    Если ТипЗнч(Документ) <> Тип("ТабличныйДокумент") Или Документ.ВысотаТаблицы < 1
        Или Документ.ШиринаТаблицы < 1 Или Документ.ВысотаТаблицы > 200 Или Документ.ШиринаТаблицы > 100 Тогда
        ВызватьИсключение "Проверка рассчитана только на свой небольшой документ";
    КонецЕсли;
КонецПроцедуры

Функция НайтиСвоюКоординату(Документ, Подпись, ПоСтроке)
    ПроверитьМалыйДокумент(Документ);
    Найдено = 0;
    Для НомерСтроки = 1 По Документ.ВысотаТаблицы Цикл
        Для НомерКолонки = 1 По Документ.ШиринаТаблицы Цикл
            Ячейка = Документ.Область(НомерСтроки, НомерКолонки);
            Если СокрЛП(Ячейка.Текст) = Подпись Тогда
                Координата = ?(ПоСтроке, НомерСтроки, НомерКолонки);
                Если Найдено <> 0 И Найдено <> Координата Тогда
                    ВызватьИсключение "Неоднозначная подпись своей оси: " + Подпись;
                КонецЕсли;
                Найдено = Координата;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    Если Найдено = 0 Тогда
        ВызватьИсключение "В реальном документе не найдена подпись " + Подпись;
    КонецЕсли;
    Возврат Найдено;
КонецФункции

Функция ПрочитатьСвоеЧисло(Ячейка)
    Если Ячейка.СодержитЗначение Тогда
        Значение = Ячейка.Значение;
        Если ТипЗнч(Значение) = Тип("Число") Тогда
            Возврат Значение;
        КонецЕсли;
        Возврат Неопределено;
    КонецЕсли;
    Текст = СтрЗаменить(СтрЗаменить(СокрЛП(Ячейка.Текст), Символ(160), ""), " ", "");
    Если Текст = "" Тогда
        Возврат Неопределено;
    КонецЕсли;
    ЕстьЦифра = Ложь;
    Для Позиция = 1 По СтрДлина(Текст) Цикл
        Знак = Сред(Текст, Позиция, 1);
        Если СтрНайти("0123456789", Знак) > 0 Тогда
            ЕстьЦифра = Истина;
        ИначеЕсли СтрНайти(",.-", Знак) = 0 Тогда
            Возврат Неопределено;
        КонецЕсли;
    КонецЦикла;
    Если Не ЕстьЦифра Тогда
        Возврат Неопределено;
    КонецЕсли;
    Возврат Число(Текст);
КонецФункции

Процедура ПроверитьСвоюЯчейку(Документ, НомерСтроки, НомерКолонки, Ожидаемое)
    Значение = ПрочитатьСвоеЧисло(Документ.Область(НомерСтроки, НомерКолонки));
    Если Значение = Неопределено Тогда
        ВызватьИсключение "Нет числа в ожидаемом пересечении собственной матрицы";
    КонецЕсли;
    Если Значение <> Ожидаемое Тогда
        ВызватьИсключение "Неверное число в пересечении: " + Строка(Значение);
    КонецЕсли;
КонецПроцедуры

Процедура ПроверитьСвоеПустоеПересечение(Документ, НомерСтроки, НомерКолонки)
    Ячейка = Документ.Область(НомерСтроки, НомерКолонки);
    Значение = ПрочитатьСвоеЧисло(Ячейка);
    Если Значение <> Неопределено Тогда
        Если Значение <> 0 Тогда
            ВызватьИсключение "В отсутствующем сочетании не должно быть ненулевой продажи";
        КонецЕсли;
    ИначеЕсли СокрЛП(Ячейка.Текст) <> "" Тогда
        ВызватьИсключение "Отсутствующая продажа должна быть пустой или числовым нулём, не посторонним текстом";
    КонецЕсли;
КонецПроцедуры

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

Процедура ПроверитьСвоюМатрицу(Документ)
    Север = НайтиСвоюКоординату(Документ, "Север", Истина);
    Юг = НайтиСвоюКоординату(Документ, "Юг", Истина);
    Книга = НайтиСвоюКоординату(Документ, "Книга", Ложь);
    Ручка = НайтиСвоюКоординату(Документ, "Ручка", Ложь);
    Если Север = Юг Или Книга = Ручка Тогда
        ВызватьИсключение "Свои магазины и товары должны занимать разные позиции";
    КонецЕсли;
    ПроверитьСвоюЯчейку(Документ, Север, Книга, 750);
    ПроверитьСвоюЯчейку(Документ, Север, Ручка, 50);
    ПроверитьСвоюЯчейку(Документ, Юг, Книга, 500);
    ПроверитьСвоеПустоеПересечение(Документ, Юг, Ручка);
    ПроверитьСвойОбщийИтог(Документ);
КонецПроцедуры

Процедура ПроверитьСвойКонтекст()
    Если Метаданные.РежимСовместимости <> Метаданные.СвойстваОбъектов.РежимСовместимости.НеИспользовать Тогда
        ВызватьИсключение "Нужен собственный стенд УчебныеМакетыТаблиц85 платформы 8.5.1.1343";
    КонецЕсли;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Учебный вывод не должен выполняться внутри чужой транзакции";
    КонецЕсли;
КонецПроцедуры
УчебныйПросмотрТаблицы85.Пульт

УчебныеМакетыТаблиц85 → Обработки → УчебныйПросмотрТаблицы85 → Формы → Пульт → Модуль

Полный модуль собственной управляемой формы Пульт; не выполнялся.

&НаКлиенте
Процедура Выполнить(Команда)
    ВыполнитьНаСервере();
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере()
    УчебныйМакетТаблицы85.ВыполнитьПример();
КонецПроцедуры

Разбор по шагам

  1. Настройки ТаблицаКомпоновкиДанных задают две оси: Магазин по строкам, Наименование по колонкам, ресурс Сумма. Компоновщик создаёт другой объект — ТаблицаМакетаКомпоновкиДанных в настоящем Макет.Тело.

  2. Имя и Идентификатор таблицы читаются как техническая диагностика. Не переименовываем идентификатор без изменения всех связей. Четыре свойства МакетШапки/МакетИтоговСтрок/МакетИтоговКолонок/МакетОбщихИтогов здесь являются строковыми ссылками на области, не ТабличныйДокумент и не произвольным текстом.

  3. Каждая непустая ссылка разрешается через реальный Макет.Макеты.Найти. Неопределено вызывает ошибку; пустая ссылка допускается как отсутствие необязательной области. Имена областей не выдумываются и не заменяются строками из другого макета.

  4. Первый свежий процессор выводит настоящий документ. Находим позиции Север/Юг и Книга/Ручка по подписям, а не R7C4. Проверяем 750/50/500 именно в их пересечениях и отсутствие ненулевой продажи Юг/Ручка.

  5. РасположениеИтоговСтрок/Колонок — отдельные записываемые свойства перечисления РасположениеИтоговКомпоновкиДанных. Сохраняем оба исходных значения; устанавливаем Начало для строк и Конец для колонок, перепроверяем и выводим заново другим процессором.

  6. После переноса подписи ищутся повторно. Поэтому число физических строк, место заголовка и позиция итога могут измениться без потери проверки данных. В реальном документе отдельно ищется числовой общий итог 1300.

  7. Оба значения расположения восстанавливаются в ветке Исключение перед повторным ВызватьИсключение, а также при успешном завершении. Третий процессор проверяет восстановленный результат тем же способом.

  8. Ячейка.Значение читается только при СодержитЗначение=True. Если вывод содержит числовой текст, читаем его после удаления обычных/неразрывных пробелов, проверки допустимых символов и преобразования Число. Заголовки и пустые ячейки не выдаём за числовой ноль; документ не изменяется.

Как проверить результат

  1. Будущий тест: F7 → собственный Пульт → Выполнить. Все три вывода должны содержать Север/Книга=750, Север/Ручка=50, Юг/Книга=500. Юг/Ручка пусто или числовой 0, но не ненулевая продажа.

  2. Общий итог 1300 должен реально присутствовать среди числовых ячеек каждого документа, а не только в таблице исходного контрольного запроса.

  3. В отладчике отдельно проверьте расположение итогов в ПослеПереноса и возврат прежних значений в Восстановленный. Проверка перечисления и чисел не доказывает визуальное расположение на экране; UI здесь не запускался.

  4. Удаление/переименование подписи, подмена числа, неверная ссылка макета или неоднозначный заголовок должны вызывать исключение, а не зелёный отчёт по отдельной копии данных.

Ожидаемый результат

Будущий результат: три настоящих табличных документа с теми же пересечениями и итогом 1300; изменено и восстановлено только расположение итогов. В 1С не проверялось.

На что обратить внимание

  1. Матрица не поддерживается выводом в ТаблицаЗначений/ДеревоЗначений: для неё используется настоящий ТабличныйДокумент. Независимый плоский расчёт не доказывает правильность матрицы.

  2. Не присваивайте случайные имена областей или новые идентификаторы: это связанные части исполняемого макета. Возможность записи строки не делает любое имя допустимым.

  3. Не суммируйте все числовые ячейки документа: детализация и итоги иначе учитываются повторно. Урок проверяет конкретные пересечения и наличие общего итога, не складывает всё оформление.

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

  5. Пример для собственной маленькой матрицы; не универсальный обход промышленного макета с иерархиями/вложенными отчётами. Никаких печати, файлов или рабочих данных. runtimeVerifiedScenarios=0.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.