|
v7: Объединение одинаковых позиций.. опять =) | ☑ | ||
---|---|---|---|---|
0
monsterZE
27.10.12
✎
13:52
|
так исторически сложилось (специфика организации), что в одной накладной не может быть одинаковых позиций. т.е. при подборе, если такая позиция уже существует - должно спрашивать и при положительном ответе складывать количество. ну и сие было реализовано с одним "ньюаносм".. =) при подборе - никаких проблем. вся вкусность начинается, при изменении существующей строки в ТЧ документа на позицию, уже существующую в ТЧ. и тут есть ньюанс =) - если меняется любая, НЕ ПОСЛЕДНЯЯ позиция - 1с проглатывает уменьшение строк ТЧ документа.. но на последней - спотыкается и просто вылетает (т.к. позиция курсора > количества строк в документе).
раньше при подборе - вызывал одну и туже процедуру - сейчас разделил. но вылез косяк при сортировке строк (т.к. 1с меняет товар в активной строке).. можно конечно запретить редактировать номер строки.. но мож есть какие-то более логичные решения?.. может кто сталкивался с подобным? |
|||
1
Джордж1
27.10.12
✎
13:53
|
нифига не понял.
но можно сначала загружать ТЧ в ТЗ, там уже обрабатывать, а по окончанию подбора загружать ТЧ обратно |
|||
2
monsterZE
27.10.12
✎
14:01
|
(1) так и есть.. и это работает, если из процедуры подбра.
но, если идет редактирование текущей строки документа - такой вариант не прокатывает.. точнее, прокатывает, как описал. |
|||
3
monsterZE
27.10.12
✎
14:32
|
хз.. поможет, нет =)
Процедура ПриНачалеРедактированияСтроки() СтарТовар = Товар; ТабЧасть = СоздатьОбъект("ТаблицаЗначений"); ТабЧасть.Очистить(); ВыгрузитьТабличнуюЧасть(ТабЧасть,"НомерСтроки,Товар,Количество,Единица"); ТабЧасть.НоваяКолонка("Код"); ТабЧасть.ВыбратьСтроки(); Пока ТабЧасть.ПолучитьСтроку()=1 Цикл ТабЧасть.Код = ТабЧасть.Товар.Код; КонецЦикла; КонецПроцедуры Процедура ПриОкончанииРедактированияСтроки() Если СтарТовар.Код<>Товар.Код Тогда стр = ПолучитьПустоеЗначение(); Если ТабЧасть.НайтиЗначение(Товар.Код,стр,"Код")=1 Тогда СтарКол = ТабЧасть.ПолучитьЗначение(стр,"Количество"); СтарЕд = ТабЧасть.ПолучитьЗначение(стр,"Единица"); СтарСтр = ТабЧасть.ПолучитьЗначение(стр,1); Отв = Вопрос("В документе уже присутствует товар"+РазделительСтрок +"["+Товар.Код+"] "+СокрЛП(Товар.Наименование)+РазделительСтрок +"в строке: "+СтарСтр+РазделительСтрок +"в количестве: "+СтарКол+" "+СтарЕд+РазделительСтрок +"Хотите продолжить выбор?","Да+Нет"); Если Отв = "Да" Тогда СтатусВозврата(0); Возврат; Иначе Товар = СтарТовар; КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры |
|||
4
monsterZE
27.10.12
✎
14:37
|
текущий вариант..
Процедура глОбъединениеКоличестваОдинаковогоТовара(Конт) Экспорт ВидДок = Конт.Вид(); ПерерасчетСуммы = 0; Если (ВидДок = "ПриходнаяНал") или (ВидДок = "РасходнаяНал") или (ВидДок = "РасходнаяНОФ") или (ВидДок = "РасходнаяКредит") или (ВидДок = "ПриходнаяКредит") или (ВидДок = "РасходнаяРеализ") или (ВидДок = "ПриходнаяРеализ") или (ВидДок = "Счет") Тогда ПерерасчетСуммы = 1; КонецЕсли; ТабЧасть = СоздатьОбъект("ТаблицаЗначений"); ТабЧасть.Очистить(); ТабДвойников = СоздатьОбъект("ТаблицаЗначений"); ТабДвойников.Очистить(); ТабОбъединенногоТовара = СоздатьОбъект("ТаблицаЗначений"); ТабОбъединенногоТовара.Очистить(); ТабОбъединенногоТовара.НоваяКолонка("Код"); ТабОбъединенногоТовара.НоваяКолонка("Колво"); Конт.ВыгрузитьТабличнуюЧасть(ТабДвойников); ТабДвойников.НоваяКолонка("Код"); ТабДвойников.НоваяКолонка("Двойник"); ТабДвойников.ВыбратьСтроки(); Пока ТабДвойников.ПолучитьСтроку()=1 Цикл ТабДвойников.Код = ТабДвойников.Товар.Код; ТабДвойников.Двойник = 1; КонецЦикла; ТабДвойников.Выгрузить(ТабЧасть); // проверка на коэффициент одинаковых позиций (приводим к одной ед.изм.) Состояние("Поиск разных ед.изм.."); ТабДвойников.Свернуть("Код,Коэффициент","Количество,Двойник"); ТабДвойников.Сортировать("Код"); старКод = ""; старКоэф = ""; ТабДвойников.ВыбратьСтроки(); Пока ТабДвойников.ПолучитьСтроку()=1 Цикл текКод = ТабДвойников.Код; текКоэф = ТабДвойников.Коэффициент; текКолво = ТабДвойников.Количество; Если (ПустоеЗначение(текКод)=1) и (ПустоеЗначение(текКоэф)=1) и (ПустоеЗначение(текКолво)=1) Тогда Продолжить; КонецЕсли; Если (текКод=старКод) и (текКоэф<>старКоэф) Тогда ТабДвойников.Коэффициент = старКоэф; ТабДвойников.Количество = текКолво*текКоэф/старКоэф; Если ТабДвойников.Количество<>Цел(ТабДвойников.Количество) Тогда Сообщить("Одинаковый товар с разными единицами измерения. Проверьте количество!"); стр = ПолучитьПустоеЗначение(); Если ТабЧасть.НайтиЗначение(текКод,стр,"Код")=0 Тогда текНаим = ""; Иначе текНаим = Строка(ТабЧасть.ПолучитьЗначение(стр,"Товар")); КонецЕсли; Сообщить("["+текКод+"] "+текНаим); КонецЕсли; КонецЕсли; старКод = текКод; старКоэф = текКоэф; КонецЦикла; //------------- ТабДвойников.Свернуть("Код","Количество,Двойник"); ТабДвойников.Сортировать("Двойник-"); Состояние("Поиск одинаковых позиций.."); ТабДвойников.ВыбратьСтроки(); Пока ТабДвойников.ПолучитьСтроку()=1 Цикл Если ТабДвойников.Двойник=1 Тогда Прервать; КонецЕсли; КодТовара = ТабДвойников.Код; стр = ПолучитьПустоеЗначение(); Если ТабЧасть.НайтиЗначение(КодТовара,стр,"Код")=0 Тогда Предупреждение("Возникла ошибка, при проверке на двойные позиции.."+РазделительСтрок+"Не найден товар с кодом ["+КодТовара+"]"); Возврат; КонецЕсли; Товар = ТабЧасть.ПолучитьЗначение(стр,"Товар"); СтароеКолвоТовара = ТабЧасть.ПолучитьЗначение(стр,"Количество"); ЕдиницаТовара = ТабЧасть.ПолучитьЗначение(стр,"Единица"); НовоеКолвоТовара = ТабДвойников.Количество; Если (ПустоеЗначение(КодТовара)=1) и (ПустоеЗначение(Товар)=1) Тогда Продолжить; КонецЕсли; Отв = Вопрос("В документе уже присутствует товар"+РазделительСтрок +"["+КодТовара+"] "+СокрЛП(Товар.Наименование)+РазделительСтрок +"в количестве: "+СтароеКолвоТовара+" "+ЕдиницаТовара+РазделительСтрок +"Новое количество: "+НовоеКолвоТовара+РазделительСтрок +"Объединить?","Да+Нет"); Если Отв = "Да" Тогда ТабОбъединенногоТовара.НоваяСтрока(); ТабОбъединенногоТовара.Код = КодТовара; ТабОбъединенногоТовара.Колво = НовоеКолвоТовара; Иначе ТабОбъединенногоТовара.НоваяСтрока(); ТабОбъединенногоТовара.Код = КодТовара; ТабОбъединенногоТовара.Колво = СтароеКолвоТовара; КонецЕсли; КонецЦикла; Состояние(""); // объединяем в основной тч ТабОбъединенногоТовара.ВыбратьСтроки(); Пока ТабОбъединенногоТовара.ПолучитьСтроку()=1 Цикл Исправлено = 0; стр = ПолучитьПустоеЗначение(); Пока ТабЧасть.НайтиЗначение(ТабОбъединенногоТовара.Код,стр,"Код")=1 Цикл Если Исправлено=0 Тогда ТабЧасть.УстановитьЗначение(стр,"Количество",ТабОбъединенногоТовара.Колво); Если ПерерасчетСуммы=1 Тогда Товар = ТабЧасть.ПолучитьЗначение(стр,"Товар"); НоваяСумма = ТабЧасть.ПолучитьЗначение(стр,"Цена")*ТабОбъединенногоТовара.Колво*ТабЧасть.ПолучитьЗначение(стр,"Коэффициент"); ТабЧасть.УстановитьЗначение(стр,"Сумма",НоваяСумма); Если Товар.СтавкаНДС = Перечисление.ЗначенияНДС.ОсновнаяСтавкаНДС Тогда СтавкаНДС = 18; ИначеЕсли Товар.СтавкаНДС = Перечисление.ЗначенияНДС.ЛьготнаяСтавкаНДС Тогда СтавкаНДС = 10; Иначе СтавкаНДС = 0; КонецЕсли; НовыйНДС = НоваяСумма*СтавкаНДС/(100+СтавкаНДС); ТабЧасть.УстановитьЗначение(стр,"НДС",НовыйНДС); КонецЕсли; ТабЧасть.УстановитьЗначение(стр,"Код",""); Исправлено = 1; Иначе ТабЧасть.УдалитьСтроку(стр); КонецЕсли; стр = ПолучитьПустоеЗначение(); КонецЦикла; КонецЦикла; Если ТабОбъединенногоТовара.КоличествоСтрок()>0 Тогда ТабЧасть.УдалитьКолонку("Код"); ТабЧасть.УдалитьКолонку("Двойник"); Конт.ЗагрузитьТабличнуюЧасть(ТабЧасть); Конт.АктивизироватьСтроку(); КонецЕсли; КонецПроцедуры |
|||
5
Torquader
27.10.12
✎
17:36
|
Почему падает 1С - понятно - при начале редактирования строки система запоминает номер строки, которая редактируется. Когда оно оканчивается, система обновляет строку в документе. Если вы число строк уменьшили, то получается, что текущая строка за пределами списка - происходит ошибка доступа к памяти.
Нужно удалять строку или до начала редактирования или после его окончания, ну или имитировать редактирование без входа в режим. |
|||
6
КонецЦикла
27.10.12
✎
17:39
|
Было такое, он-лайн резервирование
В реальном времени в записанном или новом документе отслеживались изменения резерва (как кол-во, так и товар, удаление строки и проч.) Все это сводилось к изменению кол-ва по позициям в собственной табличке SQL |
|||
7
monsterZE
27.10.12
✎
17:52
|
(5) как мысль интересно, но как реализовать, например, "удаление после" - проверять по обновлению формы?
удалять до начала редактирования - тож чет не очень представляю =) вот с эмуляцией можно что-то попробывать.. я уж хотел ничего не удалять, а просто не довать выбрать - первый пример.. но там надо тогда столбик номер_строки на редактирование запрещать.. т.к. если изменить номер, чтобы строка изменила свою позицию в списке - 1с меняет активную строку и процедура срабатывает, где не надо =) |
|||
8
Эмбеддер
27.10.12
✎
18:20
|
тема такая была с полгода назад, глюк платформы. точнее не скажу
|
|||
9
КонецЦикла
27.10.12
✎
18:33
|
(7) Извраты это все
А как другие пользователи увидят, что резерв освободился из-за замены товара? Иначе это все твое "на лету" теряет смысл А если теряет смысл, то можно в спокойной обстановке по факту записи документа сравнивать с тем что было при его открытии |
|||
10
Torquader
27.10.12
✎
18:42
|
А в чём проблема - в ПриНачалеРедактированияСтроки ставим отмену редактирования, а также делаем, что хотим - то есть показываем пользователю форму для подбора, но только одного значения. После подбора, если строка "скукожилась", то она просто делается пустой (очищаем все поля).
А вот при записи мы пустые строки просто удаляем. Если же делается добавление строки, то вместо новой строки подставляется "пустая". В общем-то, достаточно несильный геморрой из-за каких-то граблей в платформе. |
|||
11
monsterZE
27.10.12
✎
20:33
|
(9) Сорри, из поста понял только первую строчку. =)
(10) вобщем надо попробывать варианты, чтобы устроило всех.. а я расчитывал на уже готовое решение 8-D |
|||
12
ADirks
28.10.12
✎
10:56
|
Ещё можно в ПриОкончании запускать таймер, миллисекунд на 50 скажем, и там уже всё сворачивать.
Ещё можно переделать всю ТЧ на ТабличноеПоле, и там уж делай что хочешь. |
|||
13
Torquader
28.10.12
✎
12:48
|
(12) В семёрке табличное поле - это таблица значений на форме - для её редактирования прямых методов нет - нужно или внешние компоненты использовать или на каждое редактирование писать отдельные диалоги, правда, есть огромное преимущество - не бывает строки в режиме редактирования, как у табличной или многострочной части.
|
|||
14
ADirks
28.10.12
✎
13:12
|
(13) А в семёрке + 1С++ ТабличноеПоле - это ТабличноеПоле, с возможностью редактирования
|
|||
15
monsterZE
30.10.12
✎
13:37
|
Вобщем переделал я, по совету Torquader. И вот оно! =)
..Но фак! В ПриНачалеРедактированияСтроки() нет ид поля, по которому кликнул юзверь. Возможно его как-нибудь получить? Дабы остались возможности редактировать количество и ед.изм.. Процедура ПриНачалеРедактированияСтроки() СтатусВозврата(0); СтарТовар = Товар; ОткрытьПодбор("Справочник.Товары","ДляПодбора",Контекст,0,СтарТовар); УстановитьЗначениеВПодборе("Склад",Склад); КонецПроцедуры Процедура ОбработкаПодбора(Выб) ПроверкаВыделенныхПозицийТовара(Выб); Если ПустоеЗначение(СтарТовар)=0 Тогда Если СтарТовар.Код = Выб.Код Тогда Возврат; КонецЕсли; СтарТовар = ПолучитьПустоеЗначение(); Товар = Выб; Иначе ЗапросКоличестваВПодборе(Контекст,Режим,Выб); КонецЕсли; УстанЦеныРасх(Контекст); Выч_суммы_накл(Контекст); АктивизироватьСтроку(); глОбъединениеКоличестваОдинаковогоТовара(Контекст); |
|||
16
Torquader
30.10.12
✎
13:42
|
Форма.АктивныйЭлемент() скажет вам про того, кого начали править.
|
|||
17
monsterZE
30.10.12
✎
13:44
|
(16) благодарю! =)
|
|||
18
monsterZE
30.10.12
✎
15:32
|
вот еще одну шляпу получил.. тестируясь =)
если при выборе элемента (товара) - поменять его реквизит (например цену) и выбрать, то в обработке подбора в Выб - измененный реквизит видно сразу, а присваивая его табличной части дока - имеем реквизит до обновления. это если товар один и тот-же. если товары разные - все гуд. |
|||
19
monsterZE
30.10.12
✎
15:45
|
Процедура ОбработкаПодбора(Выб)
ПроверкаВыделенныхПозицийТовара(Выб); Сообщить("лок выб "+Выб.Опт_Цена); Если ПустоеЗначение(СтарТовар)=0 Тогда Если СтарТовар.Код = Выб.Код Тогда Товар = Выб; Сообщить("лок тов "+Товар.Опт_Цена); выводятся разные сообщения |
|||
20
Ёпрст
30.10.12
✎
15:52
|
Нихрена не понял, что не работает и чем штатный подбор не угодил, который умеет сам учитывать "одинаковые" строки
|
|||
21
Ёпрст
30.10.12
✎
15:52
|
.?
|
|||
22
Torquader
30.10.12
✎
15:59
|
(18) Так это старые грабли - кеширование называется, и оно в 1С реализовано не совсем верно.
Точнее, как реквизит в табличной части узнает, что его копию кто-то поменял ? Делай позиционирование на элементе и читай все данные на момент позиционирования. |
|||
23
monsterZE
30.10.12
✎
16:09
|
(22) т.е. создавать справочник и найти элемент?
|
|||
24
monsterZE
30.10.12
✎
16:09
|
(20) =) штатного подбора нет - это конфа с версии 5.3 что-ли.... некро короче =)
|
|||
25
monsterZE
30.10.12
✎
16:13
|
(20) поясняю =)
в ТЧ дока есть строка с товаром - из документа меняем реквизит этого товара и вводим его (редактирование строки) и если товар остался "стрый" 1с не обновляет его реквизиты до второго клика.. т.е. дабл ентер на строке =) хер знает как еще описать |
|||
26
monsterZE
30.10.12
✎
16:14
|
в (19) выводятся разные сообщения о цене
вот что не работает =) |
|||
27
monsterZE
30.10.12
✎
16:25
|
получается - если поменять реквизит элемента тч при редактировании строки - он обновится сразу
а, если поменять из подбора - через некоторое время.. =) |
|||
28
Ёпрст
30.10.12
✎
16:27
|
(27) через время опроса периода БД, если быть точнее.
А так, в типовых есть что-то типа глОбновитьКарточкуРеквизита.. не помню точное название, грубо - после изменения нужно заново в базе найти объект и поиметь его свойства |
|||
29
monsterZE
30.10.12
✎
16:28
|
гы гы гы =) поборол так
Товар = ПолучитьПустоеЗначение(); Товар = Выб; |
|||
30
monsterZE
30.10.12
✎
16:29
|
Процедура ОбработкаПодбора(Выб)
ПроверкаВыделенныхПозицийТовара(Выб); Сообщить("лок выб "+Выб.Опт_Цена); Если ПустоеЗначение(СтарТовар)=0 Тогда Если СтарТовар.Код = Выб.Код Тогда Товар = ПолучитьПустоеЗначение(); Товар = Выб; Сообщить("лок тов "+Товар.Опт_Цена); УстанЦеныРасх(Контекст); СтарТовар = ПолучитьПустоеЗначение(); Возврат; КонецЕсли; СтарТовар = ПолучитьПустоеЗначение(); Товар = Выб; Иначе ЗапросКоличестваВПодборе(Контекст,Режим,Выб); КонецЕсли; УстанЦеныРасх(Контекст); //Выч_суммы_накл(Контекст); АктивизироватьСтроку(); глОбъединениеКоличестваОдинаковогоТовара(Контекст); ОткрытьФормуМодально("Обработка.ВосстановлениеПослеАварии_ЗаписьРеквизитовВФайл",Контекст); КонецПроцедуры |
|||
31
Torquader
30.10.12
✎
18:59
|
(29) Тоже способ.
А разве просто присвоение значения не меняет атрибуты, или в случае выбора того же просто выбор не происходит ? |
|||
32
monsterZE
31.10.12
✎
10:32
|
(31) смотрел отладчиком - получается так:
если элемент тот-же самый - присвоение его "не обновляет" (до второго раза) если элемент другой - отрабатывает на ура (при первом) |
|||
33
monsterZE
31.10.12
✎
10:36
|
к (32) но это именно при подборе
если меняем реквизиты и отрабатывают стандартные ПриНачалеРедактированияСтроки() то реквизиты в ТЧ обновляются (с первого раза) |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |