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

SeverBap

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

Вложения

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

SeverBap

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



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

KiR

НЕ шибка опытный програмер)
11.09.2007
1 581
0
#4
А пробовал отладчиком отследить чему равно СЧ и на ЭлементОбмена.Код момент ошибки? Может тупо типы разные...
 

vbs

Well-known member
18.02.2007
1 708
1
#5
попробуй сначала перекодировать с какого-то большого числа, потом с минимального
 
H
#6
Bap Теперь понятно. Тогда в чем проблема? Сделай серии кодов в пределах подчинения и все.
 

SeverBap

Well-known member
18.09.2007
451
0
#7
has у меня было установлено серия кодов в пределах подчинения.

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

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

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

SeverBap

Well-known member
18.09.2007
451
0
#9
has Сейчас посмотрю!


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

vbs

Well-known member
18.02.2007
1 708
1
#11
Увы, не умею присоединять обработки.
Но вот код обработки перекодирования справочников - не слишком большой. Может, поможет ?
//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