Версия для печати темы (https://pro1c.org.ua/index.php?s=f479b950c6915481c3e2b16455d46297&showtopic=53942)

Нажмите сюда для просмотра этой темы в обычном формате

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 _ Программирование обычных форм 1С 8.2 и не интерфейсной логики _ Не работает сортировака Аналогов

Автор: bizisoft 03.09.19, 12:56

Добрый день.
1С8.2 Альфа-Авто 4.1.19.01

Помогите разобраться в чем загвоздка.
В форме подбора товаров (форма справочника Номенклатура) есть табличное поле в котором отображаются аналоги товаров. Это ТабличноеПоле привязано к данным РегистрСведений.ГруппыАналогов.
Основные столбцы: Артикул, Номенклатура, Производитель, Остаток. У всех в метаданных кроме Остаток указаны Данные, ТипЗначения. У Остаток Данные и соответственно ТипЗначения пустые.

Информация отображаемая в этом поле обрабатывается (отбирается) в процедуре ОбновитьИнформацию().

Вот часть кода, которая отвечает за вывод (как я понимаю) информации в табличноеполе:

Если обЗначениеНеЗаполнено(ЭлементыФормы.Список.ТекущаяСтрока) ИЛИ ЭлементыФормы.Список.ТекущаяСтрока.ЭтоГруппа Тогда
            АналогиОбъединеное.Отбор.ИдентификаторГруппы.Значение="";
        Иначе
            НоменклатураОбъект=ЭлементыФормы.Список.ТекущаяСтрока.ПолучитьОбъект();
            ИдентификаторГруппыАналогов=НоменклатураОбъект.ИдентификаторГруппыАналогов();
            Если ИдентификаторГруппыАналогов=Неопределено Тогда
                АналогиОбъединеное.Отбор.ИдентификаторГруппы.Значение="";
            Иначе
                Запрос = Новый Запрос;
                Запрос.Текст = "ВЫБРАТЬ
                               |    ОстаткиТоваровКомпанииОстатки.Номенклатура КАК Номенклатура,
                               |    ОстаткиТоваровКомпанииОстатки.Номенклатура.Артикул КАК Артикул,
                               |    ЕСТЬNULL(ОстаткиТоваровКомпанииОстатки.КоличествоОстаток, 0) КАК Количество,
                               |    ЕСТЬNULL(ОстаткиТоваровКомпанииОстатки.РезервОстаток, 0) КАК Резерв,
                               |    ОстаткиТоваровКомпанииОстатки.Номенклатура.Производитель КАК Бренд
                               |ИЗ
                               |    РегистрНакопления.ОстаткиТоваровКомпании.Остатки(
                               |            ,
                               |            Номенклатура В
                               |                (ВЫБРАТЬ РАЗЛИЧНЫЕ
                               |                    Номенклатура.Ссылка
                               |                ИЗ
                               |                    Справочник.Номенклатура КАК Номенклатура
                               |                ГДЕ
                               |                    Номенклатура.Артикул В
                               |                        (ВЫБРАТЬ
                               |                            ГруппыАналогов.Артикул КАК Артикул
                               |                        ИЗ
                               |                            РегистрСведений.ГруппыАналогов КАК ГруппыАналогов
                               |                        ГДЕ
                               |                            ГруппыАналогов.ИдентификаторГруппы = &ИдентификаторГруппы))) КАК ОстаткиТоваровКомпанииОстатки
                               |
                               |УПОРЯДОЧИТЬ ПО
                               |    Количество УБЫВ";//,  /* ЭТУ СТРОКУ добавил, чтобы сортировать по количеству,  ниже 2 закомментировал
                //               |    ОстаткиТоваровКомпанииОстатки.Номенклатура.Артикул,
                //               |    ОстаткиТоваровКомпанииОстатки.Номенклатура.Наименование";
                Запрос.УстановитьПараметр("ИдентификаторГруппы",ИдентификаторГруппыАналогов);
                ОстаткиАналогов = Запрос.Выполнить().Выбрать();
                АналогиОбъединеное.Отбор.ИдентификаторГруппы.Значение=ИдентификаторГруппыАналогов;
            КонецЕсли;
        КонецЕсли;
        АналогиОбъединеное.Отбор.ИдентификаторГруппы.Использование=Истина;    
        ЭлементыФормы.АналогиОбъединеное.НастройкаОтбора.ИдентификаторГруппы.Доступность=Ложь;


Поступила просьба сделать сортировку в этом поле по столбцу Остаток (Количество), чтобы аналоги с нулевыми остатками опускались в низ списка.

Добавил в запрос Количество УБЫВ, чтобы сортировалось по количеству, но в отображении ничего не изменилось, такое впечатление, что видимо сортировка в запросе до лампочки, т.к. после запроса выполняется какой-то код, который все равно выводит по своему.

Также еще не понятно, для чего после выполнения запроса выполняется Отбор по ИдентификаторуГруппы, это как-то запутывает.

Есть подозрение, что полученные ОстаткиАналогов в коде выше и выгруженные в ТЗ, обрабатываются в процедуре ПриВыводеСтроки и окончательно заполняет поле Остаток.
Процедура АналогиПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
    //Сообщить("При выводе строки");
    Если ОстаткиАналогов<>Неопределено Тогда
        ОстаткиАналогов.Сбросить();
        Если ОстаткиАналогов.НайтиСледующий(Новый Структура("Артикул",ДанныеСтроки.Артикул)) Тогда
            Остаток=ОстаткиАналогов.Количество-ОстаткиАналогов.Резерв;
        Иначе
            Остаток=0;
        КонецЕсли;
        ОформлениеСтроки.Ячейки.Остаток.ОтображатьТекст=Истина;
        ОформлениеСтроки.Ячейки.Остаток.Текст=Формат(Остаток,"ЧЦ=15; ЧДЦ=2; ЧН=0.00");            
    КонецЕсли;
КонецПроцедуры // АналогиПриВыводеСтроки()


Я правильно понимаю алгоритм, что в процедуре ОбновитьИнформацию() получают ТЗ с остатками, а обычным отбором список аналогов, а уже при выводе строк заполняются остатки и получается сортируй не сортируй в ТЗ отсортировать не получится.

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

Автор: Макс1С 03.09.19, 13:43

bizisoft @ Сегодня, 13:56 * ,
Давненько не клацал альфу, но: можно посмотреть ПриАктивизацииСтроки в списке товаров; возможно оттуда всё равно вызывается ОбновитьИнформацию(), а позже есть сортировка. В общем-то после "ОстаткиАналогов = Запрос.Выполнить().Выбрать();" нужно смотреть что происходит; отладчиком в этом месте если остановиться, в выборке сортировка нормальная? или попробуйте Запрос.Выполнить().Выгрузить() в этом месте в отладчике проверить.

В АналогиПриВыводеСтроки() точно не может быть сортировки, процедура срабатывает для каждой строки таблицы аналогов

Автор: fly 03.09.19, 17:17

bizisoft @ Сегодня, 13:56 * ,

Цитата(bizisoft @ 03.09.19, 13:56) *
Вот часть кода, которая отвечает за вывод (как я понимаю) информации в табличноеполе:


увы - это часть кода которая формирует "Выборку", и не является Выводом.


Цитата(Макс1С @ 03.09.19, 14:43) *
Есть подозрение, что полученные ОстаткиАналогов в коде выше и выгруженные в ТЗ, обрабатываются в процедуре ПриВыводеСтроки и окончательно заполняет поле Остаток.



Ранее упомянули, что событие при выводе строки - не может быть сортировкой.
И там всего-навсего изменяется значение "Остатка".


 Если ОстаткиАналогов.НайтиСледующий(Новый Структура("Артикул",ДанныеСтроки.Артикул)) Тогда
            Остаток=ОстаткиАналогов.Количество-ОстаткиАналогов.Резерв;
        Иначе
            Остаток=0;
КонецЕсли;



Так что надо искать далее...

Автор: bizisoft 03.09.19, 21:42

Цитата(Макс1С @ 03.09.19, 14:43) *
В АналогиПриВыводеСтроки() точно не может быть сортировки, процедура срабатывает для каждой строки таблицы аналогов

Так может поэтому и не сортирует.
Т.е. после запроса выполняется отбор в регистресведений по группе идентификатора АналогиОбъединеное.Отбор.ИдентификаторГруппы.Значение=ИдентификаторГруппыАналогов;
Соответственно список аналогов уже загружен, а в ПриВыводеСтроки происходит только заполнение ячейки "Остаток" из полученной запросом ТЗ (ОстатокАналоги).


В связи с этими моментами, получается сортировка табличного поля Аналоги не представляется возможным, если конечно не вызвать после окончания отработки ПриВыводеСтроки какой-нибудь метод на подобии АналогиОбъединеное.Порядок..., который упорядочит список

ОстаткиАналоги - объявлена в модуле как глобальная переменная.

Как и просили выкладываю процедуру ПриАктивизацииСтроки , но в ней напрямую процедура ОбновитьИнформацию не вызывается
// Динамически подключаемый обработчик ожидания
// Выполняет действия, необходимые при активизации строки табличного поля
//
Процедура СписокПриАктивизацииСтроки(Элемент)
    ПодключитьОбработчикОжидания("ОбработчикОжиданияСписокПриАктивизацииСтроки",0.1, Истина);

КонецПроцедуры //СписокПриАктивизацииСтроки()

Поэтому вот функция через которую...
// Динамически подключаемый обработчик ожидания
// Выполняет действия, необходимые при активизации строки табличного поля
//
Процедура ОбработчикОжиданияСписокПриАктивизацииСтроки()
    спСписокПриАктивизацииСтроки(ЭтаФорма, ЭлементыФормы.Список, Истина, Истина);
    // покажем информацию в нижней панели
    Если ЭлементыФормы.ДействияФормы.Кнопки.ОтображатьПанельИнформации.Пометка Тогда
        //если панель видна, то обновим
        ОбновитьИнформацию();
    КонецЕсли;
    ОтобразитьЦенуПродажи();
КонецПроцедуры // СписокПриАктивизацииСтроки()


Т.е. если подытожив последовательность:

1) Запросом получаются остатки аналогов и помещаются в глобальную переменную.
2) Заполняется список аналогов посредством метода Отбор
3) при выводе строки для каждой строки табличного поля в ТЗ остатков производится поиск с последующей подстановкой остатка.

Последовательность выполнения процедур получается следующая:
1) ПриАктивизацииСтроки -> ОбработчикОжиданияСписокПриАктивизацииСтроки() -> ОбновитьИнформацию() [Остатки запросом; Отбор]
2) ПриВыводиСтроки [поиск и подстановка остатка в список]
3) Какой метод/процедура выполняется после ПриВыводеСтроки, чтобы можно было попробовать в ней выполнить упорядочивание списка посредством .Порядок. ?

Поправьте меня если я в чем-то ошибаюсь.
Благодарю.

Автор: pablo 04.09.19, 8:17

ИМХО, без новой формы не взлетит. Новую форму проще сделать управляемой и тогда использовать динамический список.

Автор: Макс1С 04.09.19, 8:22

bizisoft @ Вчера, 22:42 * ,
Вряд ли отбор поменяет сортировку, добавьте в запросе поле = Количество - резерв КАК Остаток и уже по нему упорядочить.

Автор: bizisoft 06.09.19, 2:05

Макс1С @ 04.09.19, 9:22 * ,
В том и дело, что сортировка в запросе никак не влияет на результат, т.к. выполнение запроса по остаткам, отбор по регистру и подстановка остатков разграничено по времени и процедурам (/ Т.е. сначала идет отбор из регистра (в котором нет остатков), а потом при выводе строк в отобранные строки регистра заносится остаток.


pablo @ 04.09.19, 9:17 * ,
А что в обычных формах можно добавлять управляемые?
Я думал, что обычные формы не совместимы с управляемыми и наоборот.

Автор: pablo 06.09.19, 10:07

Совместимость определяется на уровне конфигурации в свойстве "Использовать управляемые формы в толстом клиенте в обычном режиме"

Автор: Макс1С 06.09.19, 14:44

bizisoft @ Сегодня, 3:05 * ,
Ага, вот что я пропустил:

ЭлементыФормы.АналогиОбъединеное

это РегистрСведенийСписок с добавленными на форме колонками. Действительно по добавленным сортировать не получится.
Лучше заменить этот стандартный элемент формы на простую таблицу значений, выгрузить в неё результат исходного запроса с остатками (можно добавить чего хочется), и , если сильно нужно, описать обработчики событий для нового элемента формы по аналогии со штатным.

Автор: bizisoft 17.09.19, 9:08

Макс1С @ 06.09.19, 15:44 * ,
Благодарю.
Я уже сам начал склонятся к замене этого элемента на свой, в котором будет отображаться результат полученный запросом.

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7
https://pro1c.org.ua