Имя: Пароль:
1C
1С v8
Прошу помощи по созданию кнопки вверх и вниз в СпискеСправочника
0 Valerian5557
 
23.11.17
22:28
Прошу исправить если я подошел к задаче не так.
В справочнике создал дополнительное поле "Порядок".
Нахожу индекс текущей строки.
Нахожу верхнию строку.
Далее получаю объект их и в поле "Порядок" меняю индексы.
Далее я их должен отсортировать.
После сортировке опять возвращаю Порядок = 0;
С сортировкой нечего не могу придумать.
//
ТекСсылка = ЭлементыФормы.ФизическиеЛица.ТекущаяСтрока;
        
Построитель = Новый ПостроительОтчета;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ФизическиеЛица);        
Результат = Построитель.Результат.Выгрузить();        
НайденнаяСтрока = Результат.Найти(ТекСсылка, "Ссылка");    
ИндексСтроки = Неопределено;    
Если Не НайденнаяСтрока = Неопределено Тогда
ИндексСтроки = Результат.Индекс(НайденнаяСтрока);
        КонецЕсли;

Если ИндексСтроки <> Неопределено тогда
Если ИндексСтроки<Результат.Количество() - 1 тогда
ВверхСтрока = Результат[ИндексСтроки-1].Ссылка;
Если Не ВверхСтрока= Неопределено Тогда
СледующаяСтрока = ВверхСтрока.ПолучитьОбъект();
СледующаяСтрока.РекУпоряд    = ИндексСтроки;
СледующаяСтрока.Записать();
ТекСтрП = Результат[ИндексСтроки].Ссылка;
ТекСтр = ТекСтрП.ПолучитьОбъект();
ТекСтр.РекУпоряд = ИндексСтроки-1;
ТекСтр.Записать();
КонецЕсли;
КонецЕсли;
Конеце

//
1 Mort
 
23.11.17
22:52
Было дело я создавал свой велосипед для этого, когда БСП была совсем унылой. А сейчас в БСП все неплохо, бери да внедряй.
2 Denis_CFO
 
23.11.17
22:54
(0) "Прошу исправить если я подошел к задаче не так."
В корне неверно.
Для такой цели надо использовать регистр сведений.
Причем, там ещё должно быть измерение "Пользователь".
3 Mort
 
23.11.17
22:59
(2) Чтобы у каждого был свой порядок, с блэкджеком и шлюхами. Недурно. Это очень либерально. К каждому индивидуальный подход. Не то что как в школе все с квадратной головой.
4 Valerian5557
 
23.11.17
23:01
(1) В БСП построено для УФ а у меня ОФ.
5 Denis_CFO
 
23.11.17
23:02
(3) " с блэкджеком и шлюхами." я бы вообще по-другому запилил... и кальян добавил бы....
Вот только зачем это нужно?
6 Cyberhawk
 
23.11.17
23:02
Лениво разбираться в простыне кода. Чо надо?
7 Denis_CFO
 
23.11.17
23:03
(3) Ну и точно не через ПолучитьОбъект() и Записать().
А если? да не, ну его нафиг!
8 Denis_CFO
 
23.11.17
23:04
(4) а тебе чего на данный момент для решения не хватает?
9 Mort
 
23.11.17
23:05
Так, откопал своё гм..
10 Mort
 
23.11.17
23:06
//= УПРАВЛЕНИЕ ПОРЯДКОМ =================================================================================================
// Устанавливает сортировку по порядку
Процедура ИнициализироватьПолеСписка(ТабличноеПолеСписка) Экспорт
    ТабличноеПолеСписка.Значение.Порядок.Установить("Порядок");
    Для Каждого ЭлементПорядка из ТабличноеПолеСписка.НастройкаПорядка Цикл
        ЭлементПорядка.Доступность = ложь;
    КонецЦикла;
КонецПРоцедуры

// Вызывать по кнопкам

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

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

//Подписка для объектов

Процедура УстановкаПорядкаПередЗаписью(Источник, Отказ) Экспорт
    Если Источник.Порядок = 0 Тогда
        УстановитьПорядокОбъекта(Источник);
    КонецЕсли;
КонецПроцедуры

//------------------------------------------------------------------------------------------------
// Это реализация, можно не париться.

Функция СтрокаВыше(ТабличноеПоле)
    Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда
        ТекСтрока = ТабличноеПоле.ТекущаяСтрока;
        Строки = ?(ТекСтрока.Родитель = Неопределено, ТабличноеПоле.Значение.Строки, ТекСтрока.Родитель.Строки);
        Индекс = Строки.Индекс(ТекСтрока);
        Если Индекс = 0  Тогда
            Возврат Неопределено;
        Иначе
            Возврат Строки[Индекс -1];
        КонецЕсли;
    КонецЕсли;
    Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ТаблицаЗначений") Тогда
        ТекСтрока = ТабличноеПоле.ТекущаяСтрока;
        Индекс = ТабличноеПоле.Значение.Индекс(ТекСтрока);
        Если Индекс = 0  Тогда
            Возврат Неопределено;
        Иначе
            Возврат Строки[Индекс -1];
        КонецЕсли;
    КонецЕсли;
    Если Лев(ТипЗнч(ТабличноеПоле.Значение),17) = "Справочник список" Тогда

        ТекСтрока = ТабличноеПоле.ТекущаяСтрока;
        Название = ТекСтрока.Ссылка.Метаданные().Имя;
        ИмеетВладельца = ТекСтрока.Ссылка.Метаданные().Владельцы.Количество() > 0;
        ИмеетРодителя = ТекСтрока.Ссылка.Метаданные().Иерархический;

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

Функция СтрокаНиже(ТабличноеПоле)
    Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда
        ТекСтрока = ТабличноеПоле.ТекущаяСтрока;
        Строки = ?(ТекСтрока.Родитель = Неопределено, ТабличноеПоле.Значение.Строки, ТекСтрока.Родитель.Строки);
        Индекс = Строки.Индекс(ТекСтрока);
        Если Индекс = Строки.Количество()-1  Тогда
            Возврат Неопределено;
        Иначе
            Возврат Строки[Индекс +1];
        КонецЕсли;
    КонецЕсли;
    Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ТаблицаЗначений") Тогда
        ТекСтрока = ТабличноеПоле.ТекущаяСтрока;
        Индекс = ТабличноеПоле.Значение.Индекс(ТекСтрока);
        Если Индекс = ТабличноеПоле.Значение.Количество()-1  Тогда
            Возврат Неопределено;
        Иначе
            Возврат ТабличноеПоле.Значение[Индекс + 1];
        КонецЕсли;
    КонецЕсли;
    Если Лев(ТипЗнч(ТабличноеПоле.Значение),17) = "Справочник список" Тогда

        ТекСтрока = ТабличноеПоле.ТекущаяСтрока;
        Название = ТекСтрока.Ссылка.Метаданные().Имя;
        ИмеетВладельца = ТекСтрока.Ссылка.Метаданные().Владельцы.Количество() > 0;
        ИмеетРодителя = ТекСтрока.Ссылка.Метаданные().Иерархический;

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

Процедура УстановитьПорядокОбъекта(Объект)
    Название = Объект.Метаданные().Имя;
    ИмеетВладельца = Объект.Метаданные().Владельцы.Количество() > 0;
    ИмеетРодителя = Объект.Метаданные().Иерархический;
    УсловиеРодителя = ?(ИмеетРодителя, "Родитель = &Родитель ", "");
    УсловиеВладельца = ?(ИмеетВладельца, "Владелец = &Владелец ", "");
    УсловиеИтог = ?(ИмеетРодителя ИЛИ ИмеетВладельца, "ГДЕ ", "") + УсловиеРодителя + ?(ИмеетРодителя И ИмеетВладельца, "И ", "") + УсловиеВладельца;
    
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
    |    Порядок КАК Порядок
    |ИЗ
    |    Справочник."+ Название + " " + УсловиеИтог + "
    |УПОРЯДОЧИТЬ ПО
    |    Порядок УБЫВ";
    Запрос.Параметры.Вставить("Родитель", Объект.Родитель);
    Запрос.Параметры.Вставить("Владелец", Объект.Владелец);
    
    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        Объект.Порядок = Выборка.Порядок + 1;
    Иначе
        Объект.Порядок = 1;
    КонецЕсли;
КонецПроцедуры

Функция РазрешеноИзменитьПорядок(Ссылка1, Ссылка2)
    Возврат Истина;
КонецФункции

Процедура ПоменятьПорядокМестами(Ссылка1, Ссылка2, Отказ)Экспорт
    Если НЕ РазрешеноИзменитьПорядок(Ссылка1, Ссылка2) Тогда
        Отказ = Истина;
        Возврат;
    КонецЕсли;
    
    Объект1 = Ссылка1.ПолучитьОбъект();
    Объект2 = Ссылка2.ПолучитьОбъект();
    Порядок1 = Объект1.Порядок;
    Объект1.Порядок = Объект2.Порядок;
    Объект2.Порядок = Порядок1;
    Объект1.Записать();
    Объект2.Записать();
    
КонецПроцедуры
11 Valerian5557
 
23.11.17
23:09
Спасибо.
12 Denis_CFO
 
23.11.17
23:13
(10) Прикалываешься?
Особенно вот это:
Функция РазрешеноИзменитьПорядок(Ссылка1, Ссылка2)
    Возврат Истина;
КонецФункции
13 Mort
 
24.11.17
06:48
(12) Обычная заглушка на будущий функционал (например, если хотим сделать "залоченные" элементы).  Не понадобилась судя по всему.
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший