• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

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

    Запись на курс до 25 апреля. Получить промодоступ ...

Установка порядка кодов в справочнике

  • Автор темы SeverBap
  • Дата начала
S

SeverBap

Проблема: Имется справочник (редактирование в формесписка, уникальные коды,подчиненый справочник) необходимо написать программу по смене кодов элементов справочника!!!!
Написал такой код:
Код:
Процедура глСпрПереместитьЭлемент(Конт,Направление) Экспорт
Если ПустоеЗначение(Конт.ТекущийЭлемент())=1 Тогда
Предупреждение("Сначала выберите элемент!");
Возврат;
КонецЕсли;
ТекущийСправочник=СоздатьОбъект("Справочник."+Конт.Вид());
ТекущийСправочник.ПорядокКодов();
Если Направление=-1 Тогда ТекущийСправочник.ОбратныйПорядок(1); КонецЕсли;
ТекущийСправочник.ВыбратьЭлементы();
Пока ТекущийСправочник.ПолучитьЭлемент()=1 Цикл
Если ТекущийСправочник.ТекущийЭлемент()=Конт.ТекущийЭлемент() Тогда
Если ТекущийСправочник.ПолучитьЭлемент()=0 Тогда
Предупреждение("Элемент уже крайний");
Возврат;
КонецЕсли;
Прервать;
КонецЕсли;
КонецЦикла;
НачатьТранзакцию();
ТекущийЭлемент=СоздатьОбъект("Справочник."+Конт.Вид());
ТекущийЭлемент.НайтиЭлемент(Конт.ТекущийЭлемент());
ЭлементОбмена=СоздатьОбъект("Справочник."+Конт.Вид());
ЭлементОбмена.НайтиЭлемент(ТекущийСправочник.ТекущийЭлемент());
Для Сч=1 По 9999 Цикл
Если ТекущийСправочник.НайтиПоКоду(Сч,0)=0 Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Код=ТекущийЭлемент.Код;
ТекущийЭлемент.Код=ЭлементОбмена.Код;
ЭлементОбмена.Код=Сч;
ЭлементОбмена.Записать();
ТекущийЭлемент.Записать();
ЭлементОбмена.Код=Код;
ЭлементОбмена.Записать();
ЗафиксироватьТранзакцию();
КонецПроцедуры
Выдает ошибку
Входные параметры в процедуру
Конт - контекст формы,
Направление (Значения: 1, -1) - уменьшение или увелечение кода на одно значение!!!!!
Как мона написать более реально???
 

Вложения

  • ___________.JPG
    ___________.JPG
    37,8 КБ · Просмотры: 299
  • ______.JPG
    ______.JPG
    4,5 КБ · Просмотры: 301
H

has

может я че не допонял, но что на что надо поменять? код текущего элемента на код первого?
 
S

SeverBap

has на код меньше, когда необходимо что бы он был ближе к первым числам (например с кодом 4 нам нужно повысить - тоесть код его должен быть 3, а старого который был старше 3 поменять на 4) вот и все!!!
:)



листинг процедуры нормальный рабочий - правда только если справочник неподчиненный, а этот подчинен!!!
 
K

KiR

А пробовал отладчиком отследить чему равно СЧ и на ЭлементОбмена.Код момент ошибки? Может тупо типы разные...
 
V

vbs

попробуй сначала перекодировать с какого-то большого числа, потом с минимального
 
H

has

Bap Теперь понятно. Тогда в чем проблема? Сделай серии кодов в пределах подчинения и все.
 
S

SeverBap

has у меня было установлено серия кодов в пределах подчинения.

Глючит так как справочник подчиненый, это процедура еще задействована в другом справочнике (в этой же конфигурации) - и работает!
Значит надо как-то отлавливать на подчиненность, кто знает как узнать программно подчинен справочник или нет? :)

KiR всеработает, только когда едет речь об подчиненном справочнике он не получает в выборку ни одного элемента. когда доходит до того момента начинает выдовать ошибку! Значит надо правильно определится с выборкой поставить проверку на подчиненность!!!

vbs метод хорош, но я от этого отказался!
 
H

has

Bap вобщем смотри...после ТекущийСправочник=СоздатьОбъект("Справочник."+Конт.Вид());
пишешь ТекущийСправочник.ИспользоватьВладельца(Конт.Владелец);
и ....... вуаля :)
 
S

SeverBap

has Сейчас посмотрю!


И так все реально работает, вот окончательный вариант:
Код:
Процедура глСпрПереместитьЭлемент(Конт,Направление) Экспорт
Если ПустоеЗначение(Конт.ТекущийЭлемент())=1 Тогда
Предупреждение("Сначала выберите элемент!");
Возврат;
КонецЕсли;
ТекущийСправочник=СоздатьОбъект("Справочник."+Конт.Вид());
ТекущийСправочник.ИспользоватьВладельца(Конт.Владелец);
ТекущийСправочник.ПорядокКодов();
Если Направление=-1 Тогда ТекущийСправочник.ОбратныйПорядок(1); КонецЕсли;
ТекущийСправочник.ВыбратьЭлементы();
Пока ТекущийСправочник.ПолучитьЭлемент()=1 Цикл
Если ТекущийСправочник.ТекущийЭлемент()=Конт.ТекущийЭлемент() Тогда
Если ТекущийСправочник.ПолучитьЭлемент()=0 Тогда
Предупреждение("Элемент уже крайний");
Возврат;
КонецЕсли;
Прервать;
КонецЕсли;
КонецЦикла;
НачатьТранзакцию();
ТекущийЭлемент=СоздатьОбъект("Справочник."+Конт.Вид());
ТекущийЭлемент.НайтиЭлемент(Конт.ТекущийЭлемент());
ЭлементОбмена=СоздатьОбъект("Справочник."+Конт.Вид());
ЭлементОбмена.НайтиЭлемент(ТекущийСправочник.ТекущийЭлемент());
Для Сч=1 По 9999 Цикл
Если ТекущийСправочник.НайтиПоКоду(Сч,0)=0 Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Код=ТекущийЭлемент.Код;
ТекущийЭлемент.Код=ЭлементОбмена.Код;
ЭлементОбмена.Код=Сч;
ЭлементОбмена.Записать();
ТекущийЭлемент.Записать();
ЭлементОбмена.Код=Код;
ЭлементОбмена.Записать();
ЗафиксироватьТранзакцию();
КонецПроцедуры
На форме кнопка вверх с формулой:
Код:
глСпрПереместитьЭлемент(Контекст, -1)
Кнопка вниз:
Код:
глСпрПереместитьЭлемент(Контекст, 1)

Усе пользуйтеся кому надо! :)
 
H

has

Bap а вобще имхо можно проще написать.....на досуге попробую :)
 
V

vbs

Увы, не умею присоединять обработки.
Но вот код обработки перекодирования справочников - не слишком большой. Может, поможет ?
//Mode = 1 Убрать ведущие нули
//Mode = 2 Перекодировать подряд с номера NN
//Mode = 3 Добавить ведущие нули
//Mode = 4 Добавить префикс
//RefList - список всех справочников конфигурации
Var NM,RefKind,SelRef,CodeType;
//******************************************************************************
Procedure CheckCodeType()
if CodeType = "Числовой" then
if Mode > 2 then
if EmptyValue(Prefix) = 0 then
DoMessageBox("справочник "+SelRef+" имеет числовой тип кода");1
Prefix = ""
endif
endif
endif
EndProcedure
//******************************************************************************
Procedure CheckGR()
if GR.IsGroup() = 0 then
DoMessageBox("Выберите группу справочника");
endif
EndProcedure
//******************************************************************************
Procedure WhenSelected()
SelRef = ? (RefList.CurSel() > 0,RefList.GetValue(RefList.CurSel(),RefKind),"не выбран");
KNA = RefList.CurSel();
SelRef = RefList.GetValue(KNA);
NM = MetaData.Reference(SelRef).CodeLength;
CodeType = MetaData.Reference(SelRef).CodeType;
Form.GR.SetType("Reference."+SelRef,NM,0)
EndProcedure
//******************************************************************************
Procedure Выполнить()
CheckCodeType();
if NM = 0 then
DoMessageBox("Длина кода 0"+LineBreak+"Перекодировка невозможна");
Return
endif;

if NN > 0 then
if StrLen(String(NN)) + StrLen(TrimAll(Prefix)) > NM then
DoMessageBox("Длина кода "+NM+LineBreak+"Задан слишком большой начальный номер"+LineBreak+"или слишком длинный префикс!");
Return
endif
endif;

Goods = CreateObject("Reference."+SelRef);
Goods.SelectItems();
N = NN - 1;
while Goods.GetItem() = 1 do
if EmptyValue(GR) = 0 then
if Goods.BelongsToGroup(GR) = 0 then
Continue
endif
endif;
N = N + 1;

if Mode = 1 then
Goods.Code = Trimall(String(Number(Goods.Code)));
elsif Mode = 3 then
Goods.Code = N;
elsif Mode = 2 then
if Number(Goods.Code) < 10 then Z = NM - 1;
elsif Number(Goods.Code) < 100 then Z = NM - 2;
elsif Number(Goods.Code) < 1000 then Z = NM - 3;
elsif Number(Goods.Code) < 10000 then Z = NM - 4;
else Z = NM - 5
endif;
Zero = "";
for i = 1 to Z do Zero = Zero + "0" enddo;
Goods.Code = Zero + Goods.Code;
else
Goods.Code = TrimAll(Prefix) + String(N);
endif;
Goods.write();
//Message("Новый код "+Goods.Code);
Status("Обработaн Элемент "+Goods.Наименование+" "+Goods.Code);

enddo;
DoMessageBox("Обработка Справочника выполнена !");
EndProcedure
//******************************************************************************
Procedure OnOpen()
SelRef = RefKind;
if RefList.GetListSize() = 0 then
KNA = 1;
for i = 1 to MetaData.Reference() do
RefKind = MetaData.Reference(i).Identifier;
RefList.AddValue(RefKind,MetaData.Reference(i).Present());
enddo;
SelRef = RefList.GetValue(KNA)
else //Reference уже выбран в прошлом сеансе
SelRef = RefList.GetValue(KNA);
RefList.CurSel(KNA);
WhenSelected()
endif;
RefList.CurSel(KNA);

EndProcedure
//******************************************************************************
Mode = 1
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!