Имя: Пароль:
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) Обычная заглушка на будущий функционал (например, если хотим сделать "залоченные" элементы).  Не понадобилась судя по всему.
Ошибка? Это не ошибка, это системная функция.