24.10.2013, 10:49 | #21 |
Участник
|
Ок, допустим структура данных в мапах разная. Какую структуру должны иметь данные в объединённом мапе?
Вообще говоря в разных элементах одного и тогоже мапа запросто можно хранить контейнеры разной структуры. Вопрос только в том как их обрабатывать. Как вариант можно на первое место в контейнере записывать определяющий структуру признак. Последний раз редактировалось S.Kuskov; 24.10.2013 в 10:52. |
|
24.10.2013, 10:53 | #22 |
Участник
|
Если данные разные, но Вам их все равно надо слить в одну коллекцию, можете в ключе указать префиком "I#" для Invoice и "L#" для List. Ну или просто int2str(record.TableId) + "#" Тогда при последующем переборе вы сразу будете знать, что за данные обрабатываются.
P.S. ну вот и не я один это посоветовал
__________________
http://www.axdevposts.blogspot.com Пришел, уведел.... отойди, дай другому увидеть! |
|
|
За это сообщение автора поблагодарили: user_ax (1). |
24.10.2013, 11:10 | #23 |
Участник
|
Цитата:
Сообщение от S.Kuskov
Ок, допустим структура данных в мапах разная. Какую структуру должны иметь данные в объединённом мапе?
Вообще говоря в разных элементах одного и тогоже мапа запросто можно хранить контейнеры разной структуры. Вопрос только в том как их обрабатывать. Как вариант можно на первое место в контейнере записывать определяющий структуру признак. Данные должны иметь похожую структуру. Если ключи одинаковые - нужно до внесения в общий мап просуммировать и внести уже готовое значение, если же нет - внести опять-таки в мап... Вот вопрос в обработке и стал, поэтому и обратился к вам за подсказкой. Вы с уважаемым plumbum посоветовали разделять по ключу. То есть, я могу заносить данные в один мап, но с разным ключом или как ?? Что-то вроде такого?? X++: key1 = "#List"+list.itemid+list.intsp; key2 = "#Invoice"+list.itemid+list.intsp; if (map1.lookup(key1)) map1.insert(key1, [someFields]); else map1.insert(key2,[someOtherFields]); |
|
24.10.2013, 11:35 | #24 |
Участник
|
Цитата:
Зачем вам вообще объединённый мап? может быть вам достаточно по разным мапам собрать объединённое множества ключей? а сами данные оставить в разных мапах? |
|
24.10.2013, 11:40 | #25 |
Участник
|
Цитата:
Сообщение от S.Kuskov
Похожую, но не одинаковую? "Просуммировать и внести уже готовое" ... эмм это "готовое" должно быть в виде какой структуры? как у первого мапа? как у второго? или вообще в виде новой объединённой структуры?
Зачем вам вообще объединённый мап? может быть вам достаточно по разным мапам собрать объединённое множества ключей? а сами данные оставить в разных мапах? В виде новой объединённой структуры, но с полями из первого мапа и второго. Чтобы сделать по нему один проход. У меня изначально был проход по двум мапам такого вида: X++: while (listEnumerator.moveNext()) { while(invoiceEnumerator.moveNext()) Может и достаточно, только что потом с этими ключами мне делать? Искать соотв.им значения в разных мапах ? |
|
24.10.2013, 12:04 | #26 |
Участник
|
Цитата:
Нет я имел в виду вставку разделителя в значение мапа а не в ключ. Тогда смысловая уникальность ключа будет соблюдена, и в тоже время в элементе будет сохранена информация о его структуре. |
|
24.10.2013, 12:18 | #27 |
Участник
|
Цитата:
Сообщение от S.Kuskov
Типа того. Не очень оптимально с точки зрения количества необходимых операций поиска. Оптимальнее конечно изначально всё в один мап складывать, меняя структуру контейнера элементов так сказать на лету.
Нет я имел в виду вставку разделителя в значение мапа а не в ключ. Тогда смысловая уникальность ключа будет соблюдена, и в тоже время в элементе будет сохранена информация о его структуре. То есть, ключ будет один для двух мепов, а в значение вствалять разные значения через разделитель? Хм..а если ключ сделать общий, а в значение вставлять контейнер, в котором будут все поля, разделены через разделитель какой-нибудь, тогда мап будет один...и останется придумать, как выдернуть нужное значение из этого мапа. Неплохая идея! Подумаю! |
|
24.10.2013, 12:30 | #28 |
Участник
|
Создайте мап такого типа:
X++: new Map(Types::container, Types::container); X++: [TableId, keyStr] Вся прелесть в том, что Вам нет необходимости знать, сколько полей упаковано в контейнер, до начала обработки. А во время обработки Вы можете в зависимости от TableId из ключа вызвать нужный обработчик
__________________
http://www.axdevposts.blogspot.com Пришел, уведел.... отойди, дай другому увидеть! |
|
24.10.2013, 12:30 | #29 |
Участник
|
Если Вашим кодом, то например так...
X++: while(queryRun.next()) { jour = queryRun.get(tablenum(JourListTrans)); list = queryRun.get(tablenum(JourListTrans)); invoice = queryRun.get(tablenum(InvoiceInvent)); invent = queryRun.get(tablenum(InvoiceInvent)); listKey = list.InternalSp + "#" + list.ItemId+"#"+tablenum(VendSpListTrans); invoiceKey = invoice.InternalSp + "#" + invoice.ItemId+"#"+tablenum(VendInvoiceTrans); //check in vendSpListTrans if(SharedMap.exists(listKey)) { listCon = SharedMap.lookup(listKey); listCon = conpoke(listCon,7,conpeek(listCon,7)+list.SumOfSpQty); SharedMap.insert(listKey,listCon); } else { SharedMap.insert(listKey,[jour.IDSp, jour.SpDate, jour.RContractAccount,list.InternalSp, list.ItemId, list.SpUnit, list.SumOfSpQty]); } //check in VendInvoiceTrans if(SharedMap.exists(invoiceKey)) { invoiceCon = SharedMap.lookup(invoiceKey); invoiceCon = conpoke(invoiceCon,3,conpeek(invoiceCon,3)+invoice.SumOfQty); SharedMap.insert(invoiceKey,invoiceCon); } else { SharedMap.insert(invoiceKey,[invoice.ItemId, invoice.PurchUnit, invoice.SumOfQty, invoice.InternalSp, invent.UnitId]); } } Последний раз редактировалось LeonDerCom; 24.10.2013 в 12:43. |
|
|
За это сообщение автора поблагодарили: user_ax (1). |
24.10.2013, 12:32 | #30 |
Участник
|
Цитата:
Сообщение от plumbum
Создайте мап такого типа:
X++: new Map(Types::container, Types::container); X++: [TableId, keyStr] Вся прелесть в том, что Вам нет необходимости знать, сколько полей упаковано в контейнер, до начала обработки. А во время обработки Вы можете в зависимости от TableId из ключа вызвать нужный обработчик Сделал почти так, только ключом выступает строка с преффиксом нужным, как вы ранее советовали X++: while(queryRun.next()) { jour = queryRun.get(tablenum(JourListTrans_)); list = queryRun.get(tablenum(JourListTrans)); invoice = queryRun.get(tablenum(InvoiceInvent)); invent = queryRun.get(tablenum(InvoiceInvent)); listKey = "L#"+list.InternalSp + "#" + list.ItemId+"#"+int2str(tablenum(VendSpListTrans)); invoiceKey = "I#"+invoice.InternalSp + "#" + invoice.ItemId+"#"+int2str(tablenum(VendInvoiceTrans)); //check in vendSpListTrans if(TotalMap.exists(listKey)) { listCon = TotalMap.lookup(listKey); listCon = conpoke(listCon,7,conpeek(listCon,7)+list.SumOfSpQty); TotalMap.insert(listKey,listCon); } else { TotalMap.insert(listKey,[jour.IDSp, jour.SpDate, jour.RContractAccount,list.InternalSp, list.ItemId, list.SpUnit, list.SumOfSpQty]); } //check in VendInvoiceTrans if(TotalMap.exists(invoiceKey)) { invoiceCon = TotalMap.lookup(invoiceKey); invoiceCon = conpoke(invoiceCon,3,conpeek(invoiceCon,3)+invoice.SumOfQty); TotalMap.insert(invoiceKey,invoiceCon); } else { TotalMap.insert(invoiceKey,[invoice.ItemId, invoice.PurchUnit, invoice.SumOfQty, invoice.InternalSp, invent.UnitId]); } } |
|
24.10.2013, 12:34 | #31 |
Участник
|
LeonDerCom, да, я так и сделал! Спасибо за ваш пример!
|
|
24.10.2013, 12:46 | #32 |
Участник
|
user_ax
В таком случае ключик можно уменьшить listKey = "L#"+list.InternalSp + "#" + list.ItemId; invoiceKey = "I#"+invoice.InternalSp + "#" + invoice.ItemId; |
|
24.10.2013, 12:48 | #33 |
Участник
|
|
|
24.10.2013, 12:50 | #34 |
Участник
|
Если префикс добавлять в ключ мапа, то значения из разных источников (list и Invoice) не будут складываться между собой. Т.е. грубо говоря, одна и таже номенклатура может оказаться в мапе дважды, с одним префиксом и с другим. Так и нужно?
|
|
24.10.2013, 12:52 | #35 |
Участник
|
Цитата:
Да, может оказаться одна и таже номенклатура, просто она будет присутствовать в двух разных таблицах(сейчас у меня так и просиходит). |
|
24.10.2013, 14:11 | #36 |
Участник
|
Общий мап сделал с разными ключами, теперь ищу, как за один проход вытаскивать записи с разным ключом(L и V) сразу и загонять данные для обработки.
|
|
24.10.2013, 14:15 | #37 |
Участник
|
S.Kuskov
С самого начала уже были в ключе ИД таблиц, несмотря на то, что они находились в разных МАПах, то есть в случае слияния МАПов в лоб - данные не должны были пересекаться. user_ax MapIterator X++: switch (subStr(MapIter.key(),1,1)) { case ('L'): break; case ('V'): break; } Или с учетом сортировки while - будет не очень красиво, хотя меньше действий (subStr и сравнение на V не надо будет выполнять). while (subStr(MapIter.key(),1,1)=='L') { } while (MapIter.more()) { } Последний раз редактировалось LeonDerCom; 24.10.2013 в 14:24. |
|
24.10.2013, 14:24 | #38 |
Участник
|
Цитата:
Но теперь значения в мепе повторяются по некоторым полям и так и должно быть. Только теперь пришёл к тому, что надо их разделить по ключам как-то, при этом производить всё это в одном цикле Я, наверное, уже вас достал... В данный момент я сделал через ifelse таким образом, но мои условия, которые идут ниже теряют свой смысл... X++: while(totalEnumerator.moveNext()) { totalCon = totalEnumerator.currentValue(); if(confind(totalCon,"L") == 1) { for(i = 1;i<conlen(TotalCon);i++) { jourIdsp = conpeek(totalCon,1); jourSpDate = conpeek(totalCon,2); jourRcontrAcc = conpeek(totalCon,3); listInterSp = conpeek(totalCon,4); listItemId = conpeek(totalCon,5); listSpUnit = conpeek(totalCon,6); listSpQty = conpeek(totalCon,7); } else if(confind(totalCon,'I') ==1) { invoiceItemId = conpeek(totalCon,1); invocePurchUnit = conpeek(totalCon,2); invoiceQty = conpeek(totalCon,3); invoiceInterSp = conpeek(totalCon,4); inventUnitID = conpeek(totalCon,5); } //check vendsplisttrans spunit if (listSpUnit != inventUnitID) { //проверка есть ли конвертируемая величина can_conv_sp = UnitConvert::canConvert(listSpUnit, inventUnitID,listItemId); //конвертация в нужную величину convert_spunit = UnitConvert::qty(listSpQty,listSpUnit,inventUnitID,listItemId,true,true,true); } //check vendinvoicetrans purchunit if(invocePurchUnit != inventUnitID) { can_conv_invoice = UnitConvert::canConvert(invocePurchUnit,inventUnitID,invoiceItemId); convert_purchunit = UnitConvert::qty(invoiceQty,invocePurchUnit,inventUnitID,invoiceItemId,true,true,true); } if (listSpQty == invoiceQty) { update_spec(); if (!i) { info(strfmt("@GEE10961", jourIdsp, jourSpDate, jourRcontrAcc)); counter ++; i++; } else { counter ++; } } } Последний раз редактировалось user_ax; 24.10.2013 в 14:27. |
|
24.10.2013, 14:28 | #39 |
Участник
|
Нужно всё в один цикл получается засунуть.
|
|
24.10.2013, 14:29 | #40 |
Участник
|
Судя по предыдущему сообщению user_ax соответствующие данные из разных таблиц таки нужно обрабатывать как один элемент
|
|