Решил модифицировать список номенклатуры для удобства работы, чтобы можно было видеть аналоги номенклатуры и картинки прикрепленные к номенклатуре, на одной общей форме. Для начала, перенес список номенклатуры в расширение. Добавил на форму ниже "Списка" номенклатуры вывод "Аналогов" номенклатуры (как дин. список). Связал по ключевому полю через УстановитьЗначениеПараметра дин. списка. Пока все работает нормально, при выборе в "Списке" номенклатуры ниже в "Аналогах" отображаются аналоги. Решил добавить еще на форму вывод картинок слева на форме. Добавил страницу и создал там поле ввода с видом "Поле картинки". Количество картинок генерируется автоматически по наличию вложенных картинок текущего элемента списка. и вот тут начитается полная чехарда, после заполнения картинок, пропадает содержимое основного дин. списка "Список". Заметил по отладчику, при заполнении картинок постоянно обновляется основной дин. списка "Список". В общем не могу понять почему постоянно при заполнение картинок срабатывает событие "СписокПриАктивизацииСтрокиПосле". Может кто сталкивался с таким поведением? Почему так происходит или как правильно выводить картинки? И к тому же постоянно теряется фокус текущей строки в дин. списке "Список".
Группа: Основатель
Сообщений: 13988
Из: Киев
Спасибо сказали: 4562 раз
Рейтинг: 3690.8
Цитата(Andry.Boris @ 31.08.22, 18:05)
Заметил по отладчику, при заполнении картинок постоянно обновляется основной дин. списка "Список"
Предполагаю, что вот эти все заполнения вы начинаете выполнять в обработчике события ПриАктивацииСтроки. Если так, то в нем нельзя делать вызовов к процедурам/функциям с директивой НаСервере. "Нельзя" не означает, что это невозможно сделать, это означает, что могут быть какие-то неизвестные последствия. Возможно то, что вы наблюдаете, одно из таких последствий.
Ну как бы так и есть, на событие СписокПриАктивизацииСтрокиПосле идет обращение к процедурам НаСервере А как по другому реализовать отбор и заполнение? На самом НаКлиенте все не получиться реализовать... процедура УстановитьЗначениеПараметра доступна только на сервере...
&НаКлиенте Процедура СписокПриАктивизацииСтрокиПосле(Элемент) Если Элементы.Список.ТекущиеДанные <> Неопределено Тогда ТекущаяСтрока = Элементы.Список.ТекущаяСтрока; УстановитьПараметрыОтбораАналогов(ТекущаяСтрока); Если ТекущаяСтрока <> ТекущаяНоменклатураСписка Тогда ТекущаяНоменклатураСписка = ТекущаяСтрока; СформироватьИзображения(ТекущаяНоменклатураСписка); Элементы.Список.ТекущаяСтрока = ТекущаяНоменклатураСписка; КонецЕсли; КонецЕсли; КонецПроцедуры
&НаСервере Процедура СформироватьИзображения(ТекНоменклатура) Попытка // Отключаем ненужные картинки Для ТекНомер=0 По МаксимальноеКоличествоКартинокНаФорме Цикл ОтобразитьКартинку(ТекНомер,,,Ложь); КонецЦикла; ....
В таком случае нужно вызывать код не напрямую, а через ПодключитьОбработчикОжидания с задержкой в 0.1 секунды. В большинстве случаев это помогает. В типовой на упр. формах должно быть полно примеров такого
Спасибо всем за подсказки. Разобрался немного. Убрал серверные вызовы. Перенес все на клиента. Подключил ПодключитьОбработчикОжидания. Теперь все летает и не виснет. Код привожу ниже, может кому пригодиться
Единственное, что настораживает это двойной вызов процедуры ОформлениеФормы если есть изображения для вывода. Если нет изображений для вывода, тогда один раз вызывается.
&НаСервере Процедура ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка) // Адрес заглушки при отсутствии картинки ДвоичныеДанные = БиблиотекаКартинок.НетИзображения.ПолучитьДвоичныеДанные(); АдресПустойКартинки = ПоместитьВоВременноеХранилище(ДвоичныеДанные,ЭтаФорма.УникальныйИдентификатор); // Задаем максимальное количество картинок на форме чтобы не перегружать форму элементами МаксКолвоКартинокНаФорме = 20; //Определяем массив добавляемых реквизитов для картинок ДобавляемыеРеквизиты = Новый Массив; Для Счетчик=0 По МаксКолвоКартинокНаФорме Цикл ДобавляемыеРеквизиты.Добавить(Новый РеквизитФормы("КартинкаНоменклатуры"+Строка(Счетчик),Новый ОписаниеТипов("Строка"))); КонецЦикла; //Применяем реквизиты ЭтаФорма.ИзменитьРеквизиты(ДобавляемыеРеквизиты); //Отключем страницу с изображениями Элементы.СтраницаИзображений.Видимость=Ложь; //Создаем элементы формы будущих картинок Для Счетчик=0 По МаксКолвоКартинокНаФорме Цикл СоздатьКартинкуНаСервере(Отказ,Счетчик); КонецЦикла; КонецПроцедуры
&НаКлиенте Процедура СписокПриАктивизацииСтрокиПосле(Элемент) Если Элементы.Список.ТекущиеДанные <> Неопределено Тогда //Копируем текущую строку в списке ТекСтрокаНоменклатуры = Элементы.Список.ТекущаяСтрока; //Подключаем обработчик ожидания ПодключитьОбработчикОжидания("ОформлениеФормы",0.1,Истина); //Устанавливаем отбор для таблицы аналогов Аналоги.Параметры.УстановитьЗначениеПараметра("Номенклатура", ТекСтрокаНоменклатуры); КонецЕсли; КонецПроцедуры
&НаКлиенте Процедура ОформлениеФормы() //Получаем структуру параметров наших картинок Результат = ПолучитьПараметрыКартинок(ТекСтрокаНоменклатуры,МаксКолвоКартинокНаФорме,ЭтаФорма.УникальныйИдентификатор); //Скрываем из видимости страницу с изображениями Элементы.СтраницаИзображений.Видимость=Ложь; Счетчик = 0; Если Результат.Количество()=0 Тогда //Если нет картинок, заполняем первую пустышкой Элементы["КартинкаНоменклатуры0"].Заголовок = НСтр("ru = 'Нет изображений'; uk = 'Нема зображень'"); ЭтаФорма["КартинкаНоменклатуры0"] = АдресПустойКартинки; Элементы["КартинкаНоменклатуры0"].Видимость = Истина; Счетчик = Счетчик + 1; Иначе //Если есть картинки, заполняем все по списку Для каждого ТекЗапись Из Результат Цикл СсылкаНаКартинку = ТекЗапись.Значение.СсылкаНаКартинку; СсылкаНаКартинку = ?(СсылкаНаКартинку=Неопределено,АдресПустойКартинки,СсылкаНаКартинку); ИмяКартинкиНоменклатуры = "КартинкаНоменклатуры"+Строка(Счетчик); ЭтаФорма[ИмяКартинкиНоменклатуры] = СсылкаНаКартинку; Элементы[ИмяКартинкиНоменклатуры].Заголовок = ТекЗапись.Значение.Заголовок; Элементы[ИмяКартинкиНоменклатуры].Видимость = Истина; Счетчик = Счетчик + 1; КонецЦикла; КонецЕсли; //Остальные неиспользованные картинки отключаем Для ТекНомер=Счетчик По МаксКолвоКартинокНаФорме Цикл ИмяКартинкиНоменклатуры = "КартинкаНоменклатуры"+Строка(ТекНомер); Элементы[ИмяКартинкиНоменклатуры].Видимость = Ложь; Если ЭтоАдресВременногоХранилища(ЭтаФорма[ИмяКартинкиНоменклатуры]) Тогда УдалитьИзВременногоХранилища(ЭтаФорма[ИмяКартинкиНоменклатуры]); КонецЕсли; ЭтаФорма[ИмяКартинкиНоменклатуры] = ""; КонецЦикла; //Включаем видимость страницы с изображениями Элементы.СтраницаИзображений.Видимость=Истина; КонецПроцедуры
&НаСервереБезКонтекста Функция ПолучитьПараметрыКартинок(ТекНоменклатура,МаксКолвоКартинокНаФорме,УникальныйИдентификатор) ПараметрыКартинок = Новый Структура; //Заполняем массив номенклатурой по которой будем проверять вложения масНоменклатуры = Новый Массив; масНоменклатуры.Добавить(ТекНоменклатура); //Получаем данные аналогов Выборка = РегистрыСведений.уатАналоги.Выбрать(Новый Структура("Номенклатура",ТекНоменклатура)); Пока Выборка.Следующий() Цикл //Если есть файлы у аналогов, добавляем в массив масНоменклатуры.Добавить(Выборка.Аналог); КонецЦикла; Счетчик = 0; Для каждого ТекНоменклатура Из масНоменклатуры Цикл Файлы = Новый Массив; //Получаем массив файлов вложения по каждой номенклатуре РаботаСФайлами.ЗаполнитьПрисоединенныеФайлыКОбъекту(ТекНоменклатура, Файлы); Для каждого Файл Из Файлы Цикл //Файл.Расширение //Фильтруем, только картинки показываем Если Найти("*.bmp;*.gif;*.png;*.jpeg;*.tif;*.jpg;*.ico;*.wmf;*.emf",Файл.Расширение) <> 0 Тогда Если Счетчик > МаксКолвоКартинокНаФорме Тогда Сообщить(НСтр("ru = 'Слишком много картинок.';uk = 'Дуже багато картинок.'")); Возврат ПараметрыКартинок; КонецЕсли; //Получаем ссылку на хранилище с картинкой Попытка ДвоичныеДанные = Новый ДвоичныеДанные(Файл.Том.ПолныйПутьWindows+Файл.ПутьКФайлу); СсылкаНаКартинку = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор); Исключение СсылкаНаКартинку = Неопределено; КонецПопытки; //Формируем заголовок и записываем в параметры Заголовок = СтрШаблон("Код: %1"+Символы.ПС+"Артикул: %2"+Символы.ПС+"%3",СокрЛП(ТекНоменклатура.Код), СокрЛП(ТекНоменклатура.Артикул),СокрЛП(ТекНоменклатура.Ссылка)); Запись = Новый Структура("Заголовок,СсылкаНаКартинку",Заголовок,СсылкаНаКартинку); ПараметрыКартинок.Вставить("Запись"+Формат(Счетчик,"ЧЦ=3; ЧДЦ=0; ЧН="),Запись); Счетчик = Счетчик + 1; КонецЕсли; КонецЦикла; КонецЦикла; Возврат ПараметрыКартинок; КонецФункции
Цитата(Vofka @ 01.09.22, 9:50)
Andry.Boris, [необходимо зарегистрироваться для просмотра ссылки] может будет интересно.
Спасибо! Прочитал, действительно много интересного и необычного...
&НаСервере Процедура КРАБ_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка) // Адрес заглушки при отсутствии картинки ДвоичныеДанные = БиблиотекаКартинок.КРАБ_НетИзображения.ПолучитьДвоичныеДанные(); АдресПустойКартинки = ПоместитьВоВременноеХранилище(ДвоичныеДанные,ЭтаФорма.УникальныйИдентификатор); // Задаем максимальное количество картинок на форме чтобы не перегружать форму элементами МаксКолвоКартинокНаФорме = 20; //Определяем массив добавляемых реквизитов для картинок ДобавляемыеРеквизиты = Новый Массив; Для Счетчик=0 По МаксКолвоКартинокНаФорме Цикл ДобавляемыеРеквизиты.Добавить(Новый РеквизитФормы("КартинкаНоменклатуры"+Строка(Счетчик),Новый ОписаниеТипов("Строка"))); КонецЦикла; //Применяем реквизиты ЭтаФорма.ИзменитьРеквизиты(ДобавляемыеРеквизиты); //Отключем страницу с изображениями Элементы.СтраницаИзображений.Видимость=Ложь; //Создаем элементы формы будущих картинок Для Счетчик=0 По МаксКолвоКартинокНаФорме Цикл СоздатьКартинкуНаСервере(Отказ,Счетчик); КонецЦикла; КонецПроцедуры
&НаКлиенте Процедура КРАБ_СписокПриАктивизацииСтрокиПосле(Элемент) Если Элементы.Список.ТекущиеДанные <> Неопределено Тогда //Копируем текущую строку в списке ТекСтрокаНоменклатуры = Элементы.Список.ТекущаяСтрока; //Подключаем обработчик ожидания ПодключитьОбработчикОжидания("ОформлениеФормы",0.1,Истина); //Устанавливаем отбор для таблицы аналогов Аналоги.Параметры.УстановитьЗначениеПараметра("Номенклатура", ТекСтрокаНоменклатуры); КонецЕсли; КонецПроцедуры
&НаКлиенте Процедура ОформлениеФормы() Если ОтображеннаяНоменклатура <> ТекСтрокаНоменклатуры Тогда //Получаем структуру параметров наших картинок Результат = ПолучитьПараметрыКартинок(ТекСтрокаНоменклатуры,МаксКолвоКартинокНаФорме,ЭтаФорма.УникальныйИдентификатор); //Скрываем из видимости страницу с изображениями Элементы.СтраницаИзображений.Видимость=Ложь; Счетчик = 0; Если Результат.Количество()=0 Тогда //Если нет картинок, заполняем первую пустышкой Элементы["КартинкаНоменклатуры0"].Заголовок = НСтр("ru = 'Нет изображений'; uk = 'Нема зображень'"); ЭтаФорма["КартинкаНоменклатуры0"] = АдресПустойКартинки; Элементы["КартинкаНоменклатуры0"].Видимость = Истина; Элементы["КартинкаНоменклатуры0"].Подсказка = НСтр("ru = 'Нет изображений'; uk = 'Нема зображень'"); Счетчик = Счетчик + 1; Иначе //Если есть картинки, заполняем все по списку Для каждого ТекЗапись Из Результат Цикл СсылкаНаКартинку = ТекЗапись.Значение.СсылкаНаКартинку; СсылкаНаКартинку = ?(СсылкаНаКартинку=Неопределено,АдресПустойКартинки,СсылкаНаКартинку); ИмяКартинкиНоменклатуры = "КартинкаНоменклатуры"+Строка(Счетчик); ЭтаФорма[ИмяКартинкиНоменклатуры] = СсылкаНаКартинку; Элементы[ИмяКартинкиНоменклатуры].Заголовок = ТекЗапись.Значение.Заголовок; Элементы[ИмяКартинкиНоменклатуры].Видимость = Истина; Элементы["КартинкаНоменклатуры0"].Подсказка = ТекЗапись.Значение.Подсказка; Счетчик = Счетчик + 1; КонецЦикла; КонецЕсли; //Остальные неиспользованные картинки отключаем Для ТекНомер=Счетчик По МаксКолвоКартинокНаФорме Цикл ИмяКартинкиНоменклатуры = "КартинкаНоменклатуры"+Строка(ТекНомер); Элементы[ИмяКартинкиНоменклатуры].Видимость = Ложь; Если ЭтоАдресВременногоХранилища(ЭтаФорма[ИмяКартинкиНоменклатуры]) Тогда УдалитьИзВременногоХранилища(ЭтаФорма[ИмяКартинкиНоменклатуры]); КонецЕсли; ЭтаФорма[ИмяКартинкиНоменклатуры] = ""; КонецЦикла; //Включаем видимость страницы с изображениями Элементы.СтраницаИзображений.Видимость=Истина; ОтображеннаяНоменклатура = ТекСтрокаНоменклатуры; КонецЕсли; КонецПроцедуры
&НаСервереБезКонтекста Функция ПолучитьПараметрыКартинок(ТекНоменклатура,МаксКолвоКартинокНаФорме,УникальныйИдентификатор) ПараметрыКартинок = Новый Структура; //Заполняем массив номенклатурой по которой будем проверять вложения масНоменклатуры = Новый Массив; масНоменклатуры.Добавить(ТекНоменклатура); //Получаем данные аналогов Выборка = РегистрыСведений.уатАналоги.Выбрать(Новый Структура("Номенклатура",ТекНоменклатура)); Пока Выборка.Следующий() Цикл //Если есть файлы у аналогов, добавляем в массив масНоменклатуры.Добавить(Выборка.Аналог); КонецЦикла; Счетчик = 0; Для каждого ТекЭлемент Из масНоменклатуры Цикл Файлы = Новый Массив; //Получаем массив файлов вложения по каждой номенклатуре РаботаСФайлами.ЗаполнитьПрисоединенныеФайлыКОбъекту(ТекЭлемент, Файлы); Для каждого Файл Из Файлы Цикл //Файл.Расширение //Фильтруем, только картинки показываем Если Найти("*.bmp;*.gif;*.png;*.jpeg;*.tif;*.jpg;*.ico;*.wmf;*.emf",Файл.Расширение) <> 0 Тогда Если Счетчик > МаксКолвоКартинокНаФорме Тогда Сообщить(НСтр("ru = 'Слишком много картинок.';uk = 'Дуже багато картинок.'")); Возврат ПараметрыКартинок; КонецЕсли; //Получаем ссылку на хранилище с картинкой Попытка ДвоичныеДанные = Новый ДвоичныеДанные(Файл.Том.ПолныйПутьWindows+Файл.ПутьКФайлу); СсылкаНаКартинку = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор); Исключение СсылкаНаКартинку = Неопределено; КонецПопытки; //Формируем заголовок и записываем в параметры ТекстНаименования= СокрЛП(ТекЭлемент.Ссылка); Заголовок = СтрШаблон("Код: %1"+Символы.ПС+"Артикул: %2"+Символы.ПС+"%3",СокрЛП(ТекЭлемент.Код), СокрЛП(ТекЭлемент.Артикул),?(СтрДлина(ТекстНаименования)>32,Лев(ТекстНаименования,32)+"...",ТекстНаименования)); Подсказка = СтрШаблон("Код: %1"+Символы.ПС+"Артикул: %2"+Символы.ПС+"%3",СокрЛП(ТекЭлемент.Код), СокрЛП(ТекЭлемент.Артикул),СокрЛП(ТекЭлемент.Ссылка.НаименованиеПолное)); Запись = Новый Структура("Заголовок,Подсказка,СсылкаНаКартинку",Заголовок,Подсказка,СсылкаНаКартинку); ПараметрыКартинок.Вставить("Запись"+Формат(Счетчик,"ЧЦ=3; ЧДЦ=0; ЧН="),Запись); Счетчик = Счетчик + 1; КонецЕсли; КонецЦикла; КонецЦикла; Возврат ПараметрыКартинок; КонецФункции
//Чтобы сервер не забыл об открытой форме &НаКлиенте Процедура КРАБ_ПриОткрытииПосле(Отказ) ПодключитьОбработчикОжидания("ПингСервера", 30, Ложь); КонецПроцедуры
Дополню немного статью, почему терялся фокус в таблице "Список" Ошибка была в том, что в процедуре ПолучитьПараметрыКартинок неявно использовалась переменная ТекСтрокаНоменклатуры. При передачи в процедуру, передается не само значение переменной, а ссылка указатель на переменную. Тем самым программе все равно как вы назовёте в процедуре имя принимающей переменной, по факт это у вас будет сама исходная перемененная. Ниже по коду я подсветил ошибку.
&НаКлиенте Процедура ОформлениеФормы() //Получаем структуру параметров наших картинок Результат = ПолучитьПараметрыКартинок([highlight]ТекСтрокаНоменклатуры[/highlight],МаксКолвоКартинокНаФорме,ЭтаФорма.УникальныйИдентификатор); ...
&НаСервереБезКонтекста Функция ПолучитьПараметрыКартинок([highlight]ТекНоменклатура[/highlight],МаксКолвоКартинокНаФорме,УникальныйИдентификатор) ПараметрыКартинок = Новый Структура; //Заполняем массив номенклатурой по которой будем проверять вложения масНоменклатуры = Новый Массив; масНоменклатуры.Добавить(ТекНоменклатура); //Получаем данные аналогов Выборка = РегистрыСведений.уатАналоги.Выбрать(Новый Структура("Номенклатура",ТекНоменклатура)); Пока Выборка.Следующий() Цикл //Если есть файлы у аналогов, добавляем в массив масНоменклатуры.Добавить(Выборка.Аналог); КонецЦикла; Счетчик = 0; Для каждого [highlight]ТекНоменклатура[/highlight] Из масНоменклатуры Цикл Файлы = Новый Массив; //Получаем массив файлов вложения по каждой номенклатуре ...
@Vofka - подправь оформление пожалуйста, а то что-то не получается...
Группа: Основатель
Сообщений: 13988
Из: Киев
Спасибо сказали: 4562 раз
Рейтинг: 3690.8
Andry.Boris, [ hide ] без пробелов. Я с пробелами написал, потому что не отобразится иначе в тексте. Или слева под смайликами нажмите "Спрятать", оно за вас нужный тег вставит.
1С Предприятие 8.3, 1С Предприятие 8.2, 1С Предприятие 8.1, 1С Предприятие 8.0, 1С Предприятие 7.7, Литература 1С, Общие вопросы по администрированию 1С, Методическая поддержка 1С - всё в одном месте: на Украинском 1С форуме!