Как в СКД по щелчку на какой-либо ячейке в отчете получить значение другой ячейки


Задача: по щелчку на ячейке в определенной колонке в таблице отчета нужно получить значение ячейки из другой колонки в этой же строке и передать его в другой отчет (т.е. сделать расшифровку значения другим отчетом).

Дано: платформа 1С 8.3, сделан стандартный отчет на СКД (не важно внешний или встроенный).

Задача: по двойному щелчку на ячейке в определенной колонке в таблице отчета нужно получить значение ячейки из другой колонки в этой же строке и передать его в другой отчет (т.е. сделать расшифровку значения другим отчетом).

Главный вопрос здесь — как получить значение ячейки, по которой пользователь произвел щелчок? А также как получить значение из другой ячейки в этой же строке?

В сети много примеров, но мне они показались слишком сложными, поэтому привожу здесь более простой пример.

 

Вот функция, которая возвращает значение текущей ячейки СКД отчета (той, по которой произведен щелчок) (куда вставлять данную функцию написано ниже):

// Функция - Получить значение выбранного поля отчета
//
// Параметры:
//  Расшифровка           - Число    - ИД поля, по которому произведен щелчок
//  ИменаТекущихПолей   - Массив  - Массив наименований полей, для которых нужно вернуть значение
//                                  (задает ограничение, для каких полей будет срабатывать данная функция)
//
// Возвращаемое значение:
// Строка - значение поля, по которому произведен щелчок
&НаСервере
Функция ПолучитьЗначениеВыбранногоПоляНаСервере(Расшифровка, ИменаТекущихПолей)
// получаем все данные из выведенного отчета
ДанныеОтчета = ПолучитьИзВременногоХранилища(ДанныеРасшифровки);
// по факту возвращается только одно поле под номером в переменной "Расшифровка", поэтому его и зачитываем
ПолеРасшифровки = ДанныеОтчета.Элементы.Получить(Расшифровка).ПолучитьПоля()[0];
Если Не ПолеРасшифровки = Неопределено Тогда
Если Не ИменаТекущихПолей.Найти (ПолеРасшифровки.Поле) = Неопределено Тогда
// возвращаем значение только если расшифровываем конкретное поле,
// чтобы не срабатывало на других полях
Возврат ПолеРасшифровки.Значение;
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецФункции

 

Наименование колонки текущего поля (полей) нужно для того, чтобы данная функция не срабатывала на других ячейках.

 

Вот функция, которая возвращает значение другой ячейки из этой же строки:

// Функция - Получить значение поля в строке отчета
//
// Параметры:
//  Расшифровка           - Число    - ИД поля, по которому произведен щелчок
//  ИменаТекущихПолей   - Массив  - Массив наименований полей, для которых нужно вернуть значение
//                                  (задает ограничение, для каких полей будет срабатывать данная функция)
//  ИмяНужногоПоля         - Строка  - Имя поля, из которого нужно вернуть значение
//  НужноеПолеСлева       - Булево  - Признак - справа (Ложь) или слева (Истина) от текущего находтся нужное поле
//
// Возвращаемое значение:
// Строка - значение поля, заданное в ИмяНужногоПоля
&НаСервере
Функция ПолучитьЗначениеПоляВСтрокеНаСервере(Расшифровка, ИменаТекущихПолей, ИмяНужногоПоля, НужноеПолеСлева = Истина)
ДанныеОтчета = ПолучитьИзВременногоХранилища(ДанныеРасшифровки);
ПолеРасшифровки = ДанныеОтчета.Элементы.Получить(Расшифровка).ПолучитьПоля()[0];
Если Не ПолеРасшифровки = Неопределено Тогда
Если Не ИменаТекущихПолей.Найти (ПолеРасшифровки.Поле) = Неопределено Тогда
// поиск нужного поля в направлении, которое указано в НужноеПолеСлева
ШагПоискаРасшифровки = ?(НужноеПолеСлева, -1, 1);
КоличествоПолейОтчета = ДанныеОтчета.Элементы.Количество();
СчетчикРасшифровки = Расшифровка + ШагПоискаРасшифровки;
ПоказательВыходаЗаПределыТекущихПолей = Ложь;
Пока СчетчикРасшифровки >= 0 И СчетчикРасшифровки < КоличествоПолейОтчета Цикл
ЭлементРасшифровки = ДанныеОтчета.Элементы.Получить(СчетчикРасшифровки);
Если ТипЗнч(ЭлементРасшифровки) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда
ПолеРасшифровки = ЭлементРасшифровки.ПолучитьПоля()[0];
Если ПолеРасшифровки.Поле = ИмяНужногоПоля Тогда
Возврат ПолеРасшифровки.Значение;
Иначе
Если ИменаТекущихПолей.Найти (ПолеРасшифровки.Поле) = Неопределено Тогда
ПоказательВыходаЗаПределыТекущихПолей = Истина;
Иначе
Если ПоказательВыходаЗаПределыТекущихПолей Тогда Возврат Неопределено КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
Возврат Неопределено;
КонецЕсли;
СчетчикРасшифровки = СчетчикРасшифровки + ШагПоискаРасшифровки;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецФункции

 

Помимо наименования колонки текущей ячейки (ячеек), нужно задать наименование колонки той ячейки, значение которой нужно получить, а также указать — находится ли она справа или слева от текущей/текущих (это задает направление поиска).

 

Куда вставить данный код?

Он вставляется на форму СКД отчета (если ее нет, то нужно создать типовую форму — Как добавить типовую форму для СКД)

 

Чтобы воспользоваться данными функциями понадобится создать процедуру для события ОбработкаРасшифровки элемента Результат:

 

 

В данной процедуре вызываем вышеназванные функции следующим образом:

&НаКлиенте
Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка, ДополнительныеПараметры)
ЗначениеНужногоПоляВСтроке = Неопределено;
// здесь пишем поля, на которых должна срабатывать расшифровка
МассивИменТекущихПолей = Новый Массив();
МассивИменТекущихПолей.Добавить("Пол");
МассивИменТекущихПолей.Добавить("ДатаРождения");

// ПРИМЕР 1: показывает содержимое ячейки,
// на которой кликнули (если она указана в МассивИменТекущихПолей)
//ЗначениеНужногоПоляВСтроке = ПолучитьЗначениеВыбранногоПоляНаСервере (Расшифровка, МассивИменТекущихПолей);

// ПРИМЕР 2: при щелчке на полях, указанных в МассивИменТекущихПолей,
// возвращаем ФИО
// (ФИО/Наименование находится левее от указанных полей)
ИмяНужногоПоляВСтроке = "Наименование";
ЗначениеНужногоПоляВСтроке = ПолучитьЗначениеПоляВСтрокеНаСервере (Расшифровка,
МассивИменТекущихПолей,
ИмяНужногоПоляВСтроке);

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

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

 

В зависимости от задач можно использовать первую, вторую или обе функции сразу.

Здесь приведено три примера вызова данных функций.

В принципе это всё, главное сделано, значения получены. Дальше всего лишь нужно вызвать форму другого отчета или обработки, передав полученное ранее значение как параметр.

Подробнее смотрите статью — Как при помощи БСП программно открыть внешний отчет из "Дополнительные отчеты и обработки" и передать параметры

Пример вывода отчета:

 

 

Отчет тестировался на демо-базе БСП версии 2.4.5.

Содержимое архива:

  • ВнешнийОтчетСКДПримерРасшифровка.erf — пример внешнего отчета на СКД,  для теста нужно щелкнуть на поле "Пол" или "Дата рождения". Отчет можно открывать просто через Файл-Открыть.
  • ВнешняяОбработкаПример.epf — пример внешней обработки, принимающей параметр, переданный из СКД. Нужно загрузить в "Дополнительные отчеты и обработки" (задать имя ВнешняяОбработкаПример)

11 Comments

  1. Fominro

    Спасибо, полезно.

    Reply
  2. mentozavr

    Воспользовался. Спасибо.

    Reply
  3. Ulus

    для этого вы свою форму создали в отчете.

    Например, в ERP/KA запускается общая форма «ФормаОтчета», которая интегрирована в контекст типового решения.

    При определении своей формы косячки лезут, например, при выборе/сохранение вариантов отчетом и.т.п.

    Reply
  4. MiniMuk

    В самой скд вроде есть параметр расшифровки

    Reply
  5. palsergeich

    Любая модификация отчета может привести к провалу, потому что есть чуть чуть но хардкода.

    1) Нужно заранее знать поле левее или правее, а этого нельзя гарантировать, потому что пользователь может изменить положение полей в отчете.

    2) Ориентация на имя поля, иногда их переименовывают.

    МассивИменТекущихПолей.Добавить(«Пол»);
    МассивИменТекущихПолей.Добавить(«ДатаРождения»);

    Для этой задачи увы, до сих пор ничего кроме парсинга заголовка отчета + ориентира на типы — нет. И даже это решение не дает 100% гарантии.

    Но в любом случае — статья полезная. Спасибо.

    Reply
  6. palsergeich

    (4)

    В самой скд вроде есть параметр расшифровки

    К сожалению, из расшифровки можно узнать только значение этого поля и всех родителей вверх по группировкам, а вот соседа, если он ресурс или поле детальной записи — увы нет.

    Reply
  7. MiniMuk

    (6)

    поля и всех родителей вверх по группировкам, а вот соседа, если он ресурс или поле детальной за

    точнее так

    делаем ссылку на нужное поле для расшифровки а в представление поля выводим данные которые хотим видить

    Reply
  8. palsergeich

    (7) И как представление мне поможет расшифровать отчет другим отчетом? Передать именно значение в отбор к примеру.

    А если полей несколько надо в отборы передать?

    Reply
  9. s_vidyakin

    (6) обычно нужные поля заранее известны, проще их сразу в макете запихать в расшифровку ячейки и не строить дирижабль

    Reply
  10. s_vidyakin

    (3) можно в общую форму подпихнуть дополнительный обработчик расшифровки, ведущий в какой то свой модуль при определенных условиях, а можно даже в определенную процедуру модуля объекта того же отчета. Делов-то

    Reply
  11. lmnlmn

    Простите, возможно я не до конца понял задачу, но если требуется узнать имена и значения полей по строке отчета, то почему не поступить проще? Например:

    &НаСервере
    Процедура РезультатОбработкаРасшифровкиНаСервере(НомерСтрокиТабДок);
    ДанныеРасшифр = ПолучитьИзВременногоХранилища(ДанныеРасшифровки);
    
    Для Сч = 1 По Результат.ШиринаТаблицы Цикл
    Поля = ДанныеРасшифр.Элементы[Результат.Область(НомерСтрокиТабДок, Сч).Расшифровка].ПолучитьПоля();
    
    Для Каждого Поле из Поля Цикл
    Сообщить(«Имя поля: » + Поле.Поле + «, Значение: » + Поле.Значение);
    КонецЦикла
    КонецЦикла;
    КонецПроцедуры
    
    &НаКлиенте
    Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    
    НомерСтрокиТабДок = Элемент.ТекущаяОбласть.Верх;
    
    РезультатОбработкаРасшифровкиНаСервере(НомерСтрокиТабДок);
    КонецПроцедуры
    

    Показать

    А потом уже делайте с ними что хотите.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *