Своё контекстное меню в табличном документе

1. PerlAmutor 129 15.03.18 14:22 Сейчас в теме
Понадобилось сделать контекстное меню в табличном документе и тут возникли вопросы. Есть несколько вариантов активизации контекстных меню:
а) по двойному щелчку через вызов обработки расшифровки и последующим вызовом ПоказатьВыборДействия (объекта ОбработкаРасшифровкиКомпоновкиДанных );
б) статическое (классическое) контекстное меню элемента формы.
в) по правому клику мышки (с последующим вызовом ПоказатьВыборИзМеню();

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

Плох тем, что не работает без СКД с чистым ТабличнымДокументом, т.к. не откуда взять ДанныеРасшифровки. Отметаем...

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

Третий вариант хорош всем за исключением того, что в нем невозможно создание подменю. Такой вариант (как для варианта с расшифровкой) не прокатывает:

...
                Подменю = Новый СписокЗначений;

                Для Каждого КлючИЗначение Из Структура Цикл

                    Подменю.Добавить(КлючИЗначение.Ключ, КлючИЗначение.Значение);

                КонецЦикла;

                Меню.Добавить(Подменю, "тест");
Показать


Что за несправедливость? Может быть можно как-то обмануть расшифровку, чтобы она начала работать без схемы и её настроек? (платформа 8.3.11)
По теме из базы знаний
Найденные решения
13. PerlAmutor 129 16.03.18 11:42 Сейчас в теме
(12) Я решил вопрос "экзотическим" способом. Методом проб и ошибок получился такой код (в интернете нет ничего подобного):

&НаКлиенте
Процедура ТДРезультатОбработкаДополнительнойРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)

    Если ТипЗнч(Расшифровка) = Тип("Структура") Тогда

        СтандартнаяОбработка = Ложь;

        ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
        ДанныеРасшифровки.Элементы.Добавить(Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля"),, Новый ЗначенияПолейРасшифровкиКомпоновкиДанных);

        ОбработкаРасшифровки =  Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, Новый ИсточникДоступныхНастроекКомпоновкиДанных(Новый СхемаКомпоновкиДанных));

        ДоступныеДействия=Новый Массив;
        ДоступныеДействия.Добавить(ДействиеОбработкиРасшифровкиКомпоновкиДанных.ОткрытьЗначение);

        ДополнительныеДействия = Новый СписокЗначений;
        ДополнительныеДействия.Добавить("Действие1", "Пункт 1");
        ДополнительныеДействия.Добавить("Действие2", "Пункт 2");

        Подменю = Новый СписокЗначений;
        Подменю.Добавить("Тест","Элемент подменю");
        ДополнительныеДействия.Добавить(Подменю, "Подменю");

        Оп = Новый ОписаниеОповещения("РезультатОбработкаРасшифровки_Завершение", ЭтаФорма, Расшифровка);
        ОбработкаРасшифровки.ПоказатьВыборДействия(Оп, Новый ИдентификаторРасшифровкиКомпоновкиДанных(0), ДоступныеДействия, ДополнительныеДействия, Ложь );


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

&НаКлиенте
Процедура РезультатОбработкаРасшифровки_Завершение(ВыполненноеДействие, ПараметрВыполненногоДействия, ДополнительныеПараметры) Экспорт

    Если ВыполненноеДействие = "Действие1" Тогда

        Сообщить(ТипЗнч(ДополнительныеПараметры)); // Значение расшифровки

    ИначеЕсли ВыполненноеДействие = "Действие2" Тогда

    ИначеЕсли ВыполненноеДействие=ДействиеОбработкиРасшифровкиКомпоновкиДа­нных.ОткрытьЗначение Тогда
        //ОткрытьЗначение(ПараметрВыполненногоДействия);
    КонецЕсли;

КонецПроцедуры
Показать


Т.е. я просто создаю программно пустой ИсточникДоступныхНастроекКомпоновкиДанных на основе пустой СхемуКомпоновкиДанных, затем пустые ДанныеРасшифровки, ИдентификаторРасшифровкиКомпоновкиДанных с идентификатором расшифровки "0" и добавляю 1 единственный пустой элемент ЗначенияПолейРасшифровкиКомпоновкиДанных к элементам в ДанныеРасшифровки. Не знаю насколько большой получился overhead, но меню формируется быстро, даже если эти объекты создавать каждый раз. А главное работает по правому клику мышки.
Прикрепленные файлы:
shard; MishaHD; chemezov; Chronic; Obertone; K_A_O; acanta; +7 Ответить
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. antz 15.03.18 14:27 Сейчас в теме
само контекстное меню статичное и набор его элементов невозможно изменить в зависимости от выбранной ячейки ТабличногоДокумента.


С чего это вдруг?
3. PerlAmutor 129 15.03.18 14:33 Сейчас в теме
(2) Потому, что я не нашел никакого события, которое бы вызывалось перед открытием контекстного меню.
4. antz 15.03.18 14:34 Сейчас в теме
(3)
(2) Потому, что я не нашел никакого события, которое бы вызывалось перед открытием контекстного меню.


Активизация области чем не устраивает?
5. PerlAmutor 129 15.03.18 14:44 Сейчас в теме
(4) Это событие будет вызвано как при клике левой кнопкой мышки, правой кнопкой мышки, так и при навигации клавиатурой. Предлагаете при каждой активизацией ячейки перестраивать меню?
6. antz 15.03.18 14:54 Сейчас в теме
(5) Ну тогда класть что-нибудь в расшифровку и ловить обработку дополнительной расшифровки.
7. PerlAmutor 129 15.03.18 15:56 Сейчас в теме
(6) Ну тогда возвращаемся к проблемам описанным в первом посте...
8. antz 15.03.18 16:02 Сейчас в теме
(7) не вижу никаких проблем.
Прикрепленные файлы:
ТД.epf
9. PerlAmutor 129 15.03.18 16:16 Сейчас в теме
(8) Этот вариант мне не подходит по той простой причине, что мне нужно именно динамическое меню. Заголовки команд в меню будут меняться, состав и количество элементов в подменю тоже. Их невозможно запрограммировать заранее. Управлять только видимостью элементов для меня недостаточно. Как один из вариантов можно попробовать изменять состав реквизитов формы, т.е. каждый раз формировать группу в контекстном меню заново и гонять кэш формы с клиента на сервер и обратно.

Странно, что разработчики 1С не сделали единый функционал для таких вещей.
10. antz 15.03.18 16:31 Сейчас в теме
(9) Зачем гонять-то? Один раз создать динамически и играться видимостью, не? При заполнении табличного документа это же реально?
11. PerlAmutor 129 15.03.18 17:03 Сейчас в теме
(10) Нет. Один раз создать не получится, т.к. значение ячейки выбирает пользователь, от того, что он там выберет будут и формироваться элементы меню.
12. antz 15.03.18 17:29 Сейчас в теме
(11) ну, остается гонять кэш формы)
13. PerlAmutor 129 16.03.18 11:42 Сейчас в теме
(12) Я решил вопрос "экзотическим" способом. Методом проб и ошибок получился такой код (в интернете нет ничего подобного):

&НаКлиенте
Процедура ТДРезультатОбработкаДополнительнойРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)

    Если ТипЗнч(Расшифровка) = Тип("Структура") Тогда

        СтандартнаяОбработка = Ложь;

        ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
        ДанныеРасшифровки.Элементы.Добавить(Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля"),, Новый ЗначенияПолейРасшифровкиКомпоновкиДанных);

        ОбработкаРасшифровки =  Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, Новый ИсточникДоступныхНастроекКомпоновкиДанных(Новый СхемаКомпоновкиДанных));

        ДоступныеДействия=Новый Массив;
        ДоступныеДействия.Добавить(ДействиеОбработкиРасшифровкиКомпоновкиДанных.ОткрытьЗначение);

        ДополнительныеДействия = Новый СписокЗначений;
        ДополнительныеДействия.Добавить("Действие1", "Пункт 1");
        ДополнительныеДействия.Добавить("Действие2", "Пункт 2");

        Подменю = Новый СписокЗначений;
        Подменю.Добавить("Тест","Элемент подменю");
        ДополнительныеДействия.Добавить(Подменю, "Подменю");

        Оп = Новый ОписаниеОповещения("РезультатОбработкаРасшифровки_Завершение", ЭтаФорма, Расшифровка);
        ОбработкаРасшифровки.ПоказатьВыборДействия(Оп, Новый ИдентификаторРасшифровкиКомпоновкиДанных(0), ДоступныеДействия, ДополнительныеДействия, Ложь );


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

&НаКлиенте
Процедура РезультатОбработкаРасшифровки_Завершение(ВыполненноеДействие, ПараметрВыполненногоДействия, ДополнительныеПараметры) Экспорт

    Если ВыполненноеДействие = "Действие1" Тогда

        Сообщить(ТипЗнч(ДополнительныеПараметры)); // Значение расшифровки

    ИначеЕсли ВыполненноеДействие = "Действие2" Тогда

    ИначеЕсли ВыполненноеДействие=ДействиеОбработкиРасшифровкиКомпоновкиДа­нных.ОткрытьЗначение Тогда
        //ОткрытьЗначение(ПараметрВыполненногоДействия);
    КонецЕсли;

КонецПроцедуры
Показать


Т.е. я просто создаю программно пустой ИсточникДоступныхНастроекКомпоновкиДанных на основе пустой СхемуКомпоновкиДанных, затем пустые ДанныеРасшифровки, ИдентификаторРасшифровкиКомпоновкиДанных с идентификатором расшифровки "0" и добавляю 1 единственный пустой элемент ЗначенияПолейРасшифровкиКомпоновкиДанных к элементам в ДанныеРасшифровки. Не знаю насколько большой получился overhead, но меню формируется быстро, даже если эти объекты создавать каждый раз. А главное работает по правому клику мышки.
Прикрепленные файлы:
shard; MishaHD; chemezov; Chronic; Obertone; K_A_O; acanta; +7 Ответить
14. antz 16.03.18 11:50 Сейчас в теме
(13) Тоже вчера начал копать в этом направлении, но потом закрутился. Поздравляю, в общем)
15. PerlAmutor 129 16.03.18 14:01 Сейчас в теме
(14) Только выяснился нюанс, код работает в толстом клиенте. Для тонкого клиента нужно извернутся с временным хранилищем, чтобы передать URI на ДанныеРасшифровки и СхемуКомпоновкиДанных
16. PerlAmutor 129 17.03.18 13:41 Сейчас в теме
Выяснились еще нюансы. Если в меню всего 1 элемент, то при его вызове, вместо того, чтобы показать его, она вызывает обработку действия этого меню непосредственно без показа. Еще нельзя сделать свой элемент меню неактивным, вставлять разделители (или объединять в группы).
17. lev6975 24.10.19 15:17 Сейчас в теме
Тип не определен (ДанныеРасшифровкиКомпоновкиДанных)
ДанныеРасшифровки = Новый <<?>>ДанныеРасшифровкиКомпоновкиДанных;

Это для управляемых форм годится??
Скорей всего нет... клиент не видит таких типов
18. PerlAmutor 129 24.10.19 18:33 Сейчас в теме
(17) Возможно я тестировал в толстом клиенте. Но печатные формы в тонких клиентах пользователей до сих пор работают. Стало быть я в последствии перенес ДанныеРасшифровки во временное хранилище и использовал уже адрес хранилища в конструкторе ОбработкаРасшифровкиКомпоновкиДанных.
19. lev6975 25.10.19 12:23 Сейчас в теме
(18) Надо попробовать, спасибо
20. marv-ua 22.04.21 15:36 Сейчас в теме
Если ТипЗнч(Расшифровка) = Тип("Структура") Тогда
			
			СтандартнаяОбработка = Ложь;
			
			ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровкиКомпоновкиДанных(), Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных()));
			
			ДополнительныеДействия = Новый СписокЗначений;
			ДополнительныеДействия.Добавить("Расшифровка", НСтр("ru = 'Расшифровка...'; uk = 'Розшифровка...'"));
			ДополнительныеДействия.Добавить("ОткрытьНастройку", НСтр("ru = 'Открыть настройку поля'; uk = 'Відкрити налаштування поля'"));
			
			Оп = Новый ОписаниеОповещения("ОбработкаВыбораРасшифровки", ЭтаФорма, Расшифровка);
			ОбработкаРасшифровки.ПоказатьВыборДействия(Оп, Новый ИдентификаторРасшифровкиКомпоновкиДанных(0), , ДополнительныеДействия, Ложь, Элементы.ТабличныйДокумент);
				
		КонецЕсли;
Показать


Ругается на ПоказатьВыборДейсвтвия:
Значение данных расшифровки отсутствует, либо имеет неправильный тип
{Отчет.мв_УправленческийОтчетБаланс.Форма.ФормаОтчета2021.Форма(174)}: ОбработкаРасшифровки.ПоказатьВыборДействия(Оп, Новый ИдентификаторРасшифровкиКомпоновкиДанных(0), , ДополнительныеДействия, Ложь);

по причине:
Значение данных расшифровки отсутствует, либо имеет неправильный тип

есть идеи как добить?
21. marv-ua 22.04.21 15:57 Сейчас в теме
полечилось добавлением идентификатора при помещении в хранилище

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

&НаСервере
Функция СхемаКомпоновкиДанных()
	Возврат ПоместитьВоВременноеХранилище(Новый СхемаКомпоновкиДанных, Новый УникальныйИдентификатор);
КонецФункции
Показать
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот