|
v7: Пресловутая перенумерация справочника... | ☑ | ||
---|---|---|---|---|
0
MWWRuza
гуру
03.03.17
✎
22:14
|
Я как-бы привык, что коды в справочниках чаще всего текстовые... Но, возникла задача, справочник с числовым кодом. Казалось бы, задача простейшая... Но, то-ли я заработался совсем, и не вижу какую-то свою ошибку, то-ли есть какой-то баг(фича?) ядра...
Алгоритм такой - Создаю ТЗ, с двумя колонками, "Код", и сам элемент справочника "Эл". Заполняю ее выборкой по справочнику, в ПорядокКодов(). Создаю, для чистоты эксперимента, отдельный справочник "Спр2". Дальше, бегу в цикле Для Сч = 1 по ТЗ.КоличествоСтрок() по таблице. Ищу в ТЗ по колонке "Код" значение счетчика(Сч). Если не нахожу(свободный код!) - то получаю значение из ТЗ по номеру строки(Сч) и колонке "Эл", после чего, ищу этот элемент в Спр2 и устанавливаю атрибут "Код" для этого элемента равный "Сч". Записываю. Казалось бы, все правильно... Но, получаю эффект, как при прямом удалении элемена из выборки, когда нарушается сама выборка... С каждым запуском обработки, перенумеровывается несколько элементов, а дальше не работает... Не пойму, где теряется выборка... Вот весь текст обработки: Процедура Сформировать() Спр = СоздатьОбъект("Справочник.Номенклатура"); ТЗ = СоздатьОбъект("ТаблицаЗначений"); ТЗ.НоваяКолонка("Код","Число"); ТЗ.НоваяКолонка("Эл"); Спр.ПорядокКодов(); Спр.ВыбратьЭлементы(0); Сч = 0; Пока Спр.ПолучитьЭлемент() = 1 Цикл Сч = Сч + 1; ТЗ.НоваяСтрока(); ТЗ.Код = Число(Спр.Код); ТЗ.Элемент = Спр.ТекущийЭлемент(); КонецЦикла; Спр2 = СоздатьОбъект("Справочник.Номенклатура"); ТЗ.Сортировать("Код"); Сч = 0; Для Сч = 1 По ТЗ.КоличествоСтрок() Цикл Стр = ""; Если ТЗ.НайтиЗначение(Сч,Стр,"Код") = 0 Тогда ТекЭл = ТЗ.ПолучитьЗначение(Сч,"Эл"); Если Спр2.НайтиЭлемент(ТекЭл) = 1 Тогда Спр2.УстановитьАтрибут("Код",Сч); Спр2.Записать(); Состояние("Обработано " + Сч); КонецЕсли; КонецЕсли; КонецЦикла; Сообщить("Всего элементов " + Сч); КонецПроцедуры |
|||
1
Garykom
гуру
03.03.17
✎
22:17
|
гы "Спр.ВыбратьЭлементы(0);"
Глянь нумерация не в пределах подчинения случаем? |
|||
2
Garykom
гуру
03.03.17
✎
22:20
|
Да вот это:
полная тормозная хре Все проще, переименование в два этапа - полных прохода. Сначала нумеруем все элементы (допустим максимальный номер 10 000) по порядку 10 001, 10 002, ... А затем как нуна 1,2,3 и т.д. на втором проходе |
|||
3
mehfk
03.03.17
✎
22:21
|
А учёйсом никак?
|
|||
4
MWWRuza
гуру
03.03.17
✎
22:30
|
1. Справочник не подчиненный.
2. Я никуда не спешу, и понимаю, что с точки зрения производительности, это не оптимально... Но, на это есть свои причины... Если код в пределах общего количества элементов, то хотелось бы оставить его на месте(привязка внутренних ШК к коду), и только те, которые за пределами количества элементов, перенумеровать, "всунов" в пустые места. 3. "А учёйсом никак?" - не понял... |
|||
5
Garykom
гуру
03.03.17
✎
22:32
|
(4) Тогда точно не то делаешь если хочешь "всунуть".
Тебе просто нужны 2 списка: 1. Список пустых номеров 2. Список выходящих за пределы элементов Далее нумеруешь 2-й список подряд номерами из 1-го, один уй 2 прохода |
|||
6
Garykom
гуру
03.03.17
✎
22:42
|
(5)+ самый быстрый способ получить "список пустых" это массив заполняем где куда по номеру пишем 1, а по умолчанию 0.
Далее проход по массиву и вот значения с 0 пустые. Можно и через ТЗ в 2 колонки. |
|||
7
Garykom
гуру
03.03.17
✎
22:42
|
(6)+ хотя нафик 2 колонки в ТЗ, там же нумерация есть = массив
|
|||
8
mehfk
03.03.17
✎
22:44
|
||||
9
MWWRuza
гуру
03.03.17
✎
22:45
|
Да, все верно...
Но, сбой в нумерации пошел недавно, и по большому счету, мне наплевать на ихние проблемы, возникшие после сбоя... Поэтому, я и решил начать перенумеровывать сквозняком, с момента возникновения сбоя. Не нашли в ТЗ код, присваиваем текущему элементу(полученному из тз по порядку) новый, который по порядку, свободный(мы же его не нашли в ТЗ, значит он свободный). Далее, если попадается код, который совпадает со Сч, пропускаем, ничего с ним не делая, пусть он остается на своем месте. |
|||
10
Garykom
гуру
03.03.17
✎
22:56
|
(9) Научитесь правильно выделять отдельные блоки-подпрограммы в алгоритме и оформлять их в виде отдельных процедур/функций.
Будет проще/быстрее программировать и меньше икать придется когда ваш код кто то другой увидит: Функция ПереименоватьЭлемент(Элемент, НовыйНомер) Элемент.УстановитьАтрибут("Код", НовыйНомер); Элемент.Записать(); КонецФункции и т.д. |
|||
11
MWWRuza
гуру
03.03.17
✎
22:58
|
Ок. Правильно, сейчас перепишу... Просто, обработка - детский сад, поэтому не стал сразу так делать.
|
|||
12
MWWRuza
гуру
03.03.17
✎
23:06
|
Процедура ИзменитьКод(ТЗ,Сч)
Спр = СоздатьОбъект("Справочник.Номенклатура"); ТекЭл = ТЗ.ПолучитьЗначение(Сч,"Эл"); Если Спр.НайтиЭлемент(ТекЭл) = 1 Тогда Спр.УстановитьАтрибут("Код",Сч); Спр.Записать(); Состояние("Обработано " + Сч); КонецЕсли; КонецПроцедуры Процедура Сформировать() Спр = СоздатьОбъект("Справочник.Номенклатура"); ТЗ = СоздатьОбъект("ТаблицаЗначений"); ТЗ.НоваяКолонка("Код","Число"); ТЗ.НоваяКолонка("Эл"); Спр.ПорядокКодов(); Спр.ВыбратьЭлементы(0); Сч = 0; Пока Спр.ПолучитьЭлемент() = 1 Цикл Сч = Сч + 1; ТЗ.НоваяСтрока(); ТЗ.Код = Число(Спр.Код); ТЗ.Эл = Спр.ТекущийЭлемент(); КонецЦикла; ТЗ.Сортировать("Код"); Сч = 0; Для Сч = 1 По ТЗ.КоличествоСтрок() Цикл Стр = ""; Если ТЗ.НайтиЗначение(Сч,Стр,"Код") = 0 Тогда ИзменитьКод(ТЗ,Сч); КонецЕсли; КонецЦикла; Сообщить("Всего элементов " + Сч); КонецПроцедуры |
|||
13
MWWRuza
гуру
03.03.17
✎
23:14
|
Прокоментировал:
Процедура ИзменитьКод(ТЗ,Сч) Спр = СоздатьОбъект("Справочник.Номенклатура"); ТекЭл = ТЗ.ПолучитьЗначение(Сч,"Эл"); Если Спр.НайтиЭлемент(ТекЭл) = 1 Тогда Спр.УстановитьАтрибут("Код",Сч); Спр.Записать(); Состояние("Обработано " + Сч); КонецЕсли; КонецПроцедуры Процедура Сформировать() Спр = СоздатьОбъект("Справочник.Номенклатура"); ТЗ = СоздатьОбъект("ТаблицаЗначений"); ТЗ.НоваяКолонка("Код","Число"); ТЗ.НоваяКолонка("Эл"); Спр.ПорядокКодов(); Спр.ВыбратьЭлементы(0); Сч = 0; Пока Спр.ПолучитьЭлемент() = 1 Цикл Сч = Сч + 1; ТЗ.НоваяСтрока(); ТЗ.Код = Число(Спр.Код); ТЗ.Эл = Спр.ТекущийЭлемент(); КонецЦикла; // Заполнили, тут все ОК. ТЗ.Сортировать("Код"); // На всякий случай - танцы с бубном(ТБ) Сч = 0; Для Сч = 1 По ТЗ.КоличествоСтрок() Цикл Стр = ""; Если ТЗ.НайтиЗначение(Сч,Стр,"Код") = 0 Тогда // Не нашли, код сбободный, следующему элементу можно его присвоить ИзменитьКод(ТЗ,Сч); КонецЕсли; КонецЦикла; Сообщить("Всего элементов " + Сч); КонецПроцедуры |
|||
14
vova1122
06.03.17
✎
17:17
|
Когда-то давно сделал для себя такую обработку. Товары с кодом большим от заданного расставляю в пустые места. Если товара больше чем пустых мест, то переместятся только с те у которых наибольшей номер.
Если актуально, могу поделится. |
|||
15
Злопчинский
06.03.17
✎
18:01
|
возьмите уже наконец набор универсальных отчетов и обработок с диска ИТС
|
|||
16
vova1122
06.03.17
✎
18:28
|
(15) какраз ту задачу что нужно автору, и когда-то было нужно мне не выполняет ни одна из обработок из ИТС
|
|||
17
Злопчинский
06.03.17
✎
18:54
|
(16) что? пернумеровать элементы справочника, чтобы коды шли по порядку?
|
|||
18
vova1122
06.03.17
✎
19:01
|
(17) прочтите внимательно
|
|||
19
Ёпрст
06.03.17
✎
19:03
|
(13) зачетная трава
|
|||
20
Ёпрст
06.03.17
✎
19:10
|
Если че, ты своим поиском счетчик цикла сбиваешь нахрен :)
Почитай на досуге, как работает метод НайтиЗначение и что он возвращает в параметры метода. |
|||
21
Ёпрст
06.03.17
✎
19:10
|
и.. больше так не делай.
|
|||
22
vova1122
06.03.17
✎
19:26
|
(17) Для старых товаров с небольшим номером оставить те же номера. Их не перенумеровывать.
А товары которые недавно созданы (с большим номером) перенумеровать - присвоить новый номер(из пропущенных номеров) |
|||
23
Злопчинский
06.03.17
✎
22:48
|
(22) такая задача имеет смысл только в том случае если в код элемента справочника - который для тупой нумерации и все - вкладывать дополнительные смыслы
|
|||
24
Злопчинский
06.03.17
✎
22:49
|
(22) фигня полная
Ибо нет критерия что такое старый и новый товары |
|||
25
Злопчинский
06.03.17
✎
22:52
|
(22) тупой шаблонтпишется на коленке
Получаем список неиспользуемых номеров И в движении по обратной выборке используем их Неинтересно |
|||
26
MWWRuza
гуру
07.03.17
✎
01:28
|
Сделал я еще в тот-же день, вот так, ищу не в ТЗ а сразу в справочнике, так отрабатывает нормально:
Процедура Сформировать() Спр = СоздатьОбъект("Справочник.Номенклатура"); ТЗ = СоздатьОбъект("ТаблицаЗначений"); ТЗ.НоваяКолонка("Код","Число"); ТЗ.НоваяКолонка("Эл"); Спр.ПорядокКодов(); Спр.ВыбратьЭлементы(0); Сч = 0; Пока Спр.ПолучитьЭлемент() = 1 Цикл Сч = Сч + 1; ТЗ.НоваяСтрока(); ТЗ.Код = Число(Спр.Код); ТЗ.Эл = Спр.ТекущийЭлемент(); КонецЦикла; // Заполнили, тут все ОК. ТЗ2 = СоздатьОбъект("ТаблицаЗначений"); ТЗ.Выгрузить(ТЗ2); ТЗ.Сортировать("Код"); // На всякий случай - танцы с бубном(ТБ) НачатьТранзакцию(); Сч = 0; ТЗ.ВыбратьСтроки(); Сч = 0; Сч2 = 0; Пока ТЗ.ПолучитьСтроку() = 1 Цикл Сч = Сч + 1; Стр = ""; Если Спр.НайтиПоКоду(Сч) = 0 Тогда Если Спр.НайтиЭлемент(ТЗ.ПолучитьЗначение(Сч,"Эл")) =1 Тогда Спр.УстановитьАтрибут("Код",Сч); Спр.Записать(); Если Сч%500 = 0 Тогда Состояние("Обработано " + Сч); ЗафиксироватьТранзакцию(); НачатьТранзакцию(); КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; ЗафиксироватьТранзакцию(); Сообщить("Всего элементов " + Сч); КонецПроцедуры Да, все таки видимо в этом дело: "Если че, ты своим поиском счетчик цикла сбиваешь нахрен :) " |
|||
27
MWWRuza
гуру
07.03.17
✎
01:48
|
"как работает метод НайтиЗначение и что он возвращает в параметры метода"
Ну... И что? Параметры: <Знач> - значение для поиска. <Строка> - идентификатор переменной, куда возвращается номер найденной строки. Если при вызове метода передать в этот параметр номер строки, то поиск будет осуществляться только по указанной строке. <Колонка> - номер или идентификатор колонки, возвращает номер найденной колонки. Идентификатор переменной, куда возвращается номер найденной колонки. Если при вызове метода передать в этот параметр номер или идентификатор колонки, то поиск будет осуществляться только по указанной колонке. Цикл по ТЗ у меня принудительный, не выборкой "Пока получить", а просто по счетчику от 1 до КоличествоСтрок(), на каждом шаге цикла я параметр поиска, перед поиском, делаю пустым - Стр = "". Какое отношение найденный или не найденный номер строки имеет к циклу? Объясните бестолковому плиз, не ради прикладной задачи, ее я решил по другому, а на будущее... |
|||
28
MWWRuza
гуру
07.03.17
✎
02:00
|
"такая задача имеет смысл только в том случае если в код элемента справочника - который для тупой нумерации и все - вкладывать дополнительные смыслы"
Именно так. К кодам справочника привязаны ШК весового товара, а так же просто внутренние ШК. Их хоть и не много, но встречаются. По этому и была задача, по возможности оставить все на своих местах, и перенумеровать только явные "косяки", те элементы, код которых больше чем количество элементов в справочнике. PS Если че - я не курю, не только траву, а даже сигареты:))) |
|||
29
vova1122
07.03.17
✎
09:47
|
(26) мне кажется вы не добились того что хотели. По этому алгоритму будет не заполнение пропущенных номеров, а тупо уплотнение списка.
Для ясности пример. У вас было: 1. Товар1 4. Товар4 5. Товар5 8. Товар8 10. Товар10 А попучилось: 1. Товар1 2. Товар4 3. Товар5 4. Товар8 5. Товар10 Такого результата вы хотели? Или может такого: 1. Товар1 2. Товар8 3. Товар10 4. Товар4 5. Товар5 |
|||
30
Злопчинский
07.03.17
✎
10:27
|
Думаю в рамках задачи автора - одновалентно
|
|||
31
MWWRuza
гуру
08.03.17
✎
21:40
|
Ну, да... Задача решена, полностью. По логике задачи, именно такое "уплотнение" полностью решает все проблемы.
Но, как в том анекдоте - "Ложечки то нашлись, но осадочек остался!"... Так и не понял, где в первоначальном алгоритме ошибка:( |
|||
32
MWWRuza
гуру
08.03.17
✎
22:08
|
Наверно в ДНК :(
|
|||
33
vova1122
09.03.17
✎
10:54
|
(31) Ты создал один раз таблицу значений. И в процессе переименовании кодов данные в таблице значений не изменяются.
Например в таблице значений нет товара с кодом 10. Дальше ты присвоил номер 10 товару который до этого имел номер 11. Получается, что в базе уже нет товара с кодом 11, а в таблице значений он есть. Получается нестыковка..... На следующем шаге когда ищешь в таблице значений товар с кодом 11, обработка его пропускает, так как в он есть в ТЗ. А в базе то его нет!!!! (ты его переименовал на номер 10 на предыдущем щаге)!!!!! |
|||
34
MWWRuza
гуру
09.03.17
✎
21:57
|
Точно...
Спасибо! Заработался я совсем, такую очевидную вещь не заметил... |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |