AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Функционал
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 24.10.2013, 10:49   #21  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от user_ax Посмотреть сообщение
Так данные-то разные, для того и разделяю.
Ок, допустим структура данных в мапах разная. Какую структуру должны иметь данные в объединённом мапе?

Вообще говоря в разных элементах одного и тогоже мапа запросто можно хранить контейнеры разной структуры. Вопрос только в том как их обрабатывать. Как вариант можно на первое место в контейнере записывать определяющий структуру признак.

Последний раз редактировалось S.Kuskov; 24.10.2013 в 10:52.
Старый 24.10.2013, 10:53   #22  
plumbum is offline
plumbum
Участник
Соотечественники
 
182 / 86 (3) ++++
Регистрация: 07.12.2007
Адрес: Vienna, AT
Если данные разные, но Вам их все равно надо слить в одну коллекцию, можете в ключе указать префиком "I#" для Invoice и "L#" для List. Ну или просто int2str(record.TableId) + "#" Тогда при последующем переборе вы сразу будете знать, что за данные обрабатываются.

P.S. ну вот и не я один это посоветовал
__________________
http://www.axdevposts.blogspot.com
Пришел, уведел.... отойди, дай другому увидеть!
За это сообщение автора поблагодарили: user_ax (1).
Старый 24.10.2013, 11:10   #23  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Ок, допустим структура данных в мапах разная. Какую структуру должны иметь данные в объединённом мапе?

Вообще говоря в разных элементах одного и тогоже мапа запросто можно хранить контейнеры разной структуры. Вопрос только в том как их обрабатывать. Как вариант можно на первое место в контейнере записывать определяющий структуру признак.
Я вот сижу и думаю, как записывать в мап 2 контейнера, как вы советуете...И как их обрабатывать после этого.
Данные должны иметь похожую структуру. Если ключи одинаковые - нужно до внесения в общий мап просуммировать и внести уже готовое значение, если же нет - внести опять-таки в мап...

Вот вопрос в обработке и стал, поэтому и обратился к вам за подсказкой.

Вы с уважаемым 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  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от user_ax Посмотреть сообщение
Данные должны иметь похожую структуру. Если ключи одинаковые - нужно до внесения в общий мап просуммировать и внести уже готовое значение, если же нет - внести опять-таки в мап...
Похожую, но не одинаковую? "Просуммировать и внести уже готовое" ... эмм это "готовое" должно быть в виде какой структуры? как у первого мапа? как у второго? или вообще в виде новой объединённой структуры?

Зачем вам вообще объединённый мап? может быть вам достаточно по разным мапам собрать объединённое множества ключей? а сами данные оставить в разных мапах?
Старый 24.10.2013, 11:40   #25  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Похожую, но не одинаковую? "Просуммировать и внести уже готовое" ... эмм это "готовое" должно быть в виде какой структуры? как у первого мапа? как у второго? или вообще в виде новой объединённой структуры?

Зачем вам вообще объединённый мап? может быть вам достаточно по разным мапам собрать объединённое множества ключей? а сами данные оставить в разных мапах?
Нет, не одинаковую, вы правы.
В виде новой объединённой структуры, но с полями из первого мапа и второго.


Чтобы сделать по нему один проход.
У меня изначально был проход по двум мапам такого вида:

X++:
 while (listEnumerator.moveNext())
    {
        while(invoiceEnumerator.moveNext())
Но этот проход был неккоректен, так как вначале цикл шёл по всему внутреннему мапу и по первому элементу внешнего, а мне нужно чтобы одновременно шёл цикл...
Может и достаточно, только что потом с этими ключами мне делать? Искать соотв.им значения в разных мапах ?
Старый 24.10.2013, 12:04   #26  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от user_ax Посмотреть сообщение
Может и достаточно, только что потом с этими ключами мне делать? Искать соотв.им значения в разных мапах ?
Типа того. Не очень оптимально с точки зрения количества необходимых операций поиска. Оптимальнее конечно изначально всё в один мап складывать, меняя структуру контейнера элементов так сказать на лету.
Цитата:
Сообщение от user_ax Посмотреть сообщение
Вы с уважаемым plumbum посоветовали разделять по ключу. То есть, я могу заносить данные в один мап, но с разным ключом или как ??
Нет я имел в виду вставку разделителя в значение мапа а не в ключ. Тогда смысловая уникальность ключа будет соблюдена, и в тоже время в элементе будет сохранена информация о его структуре.
Старый 24.10.2013, 12:18   #27  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Типа того. Не очень оптимально с точки зрения количества необходимых операций поиска. Оптимальнее конечно изначально всё в один мап складывать, меняя структуру контейнера элементов так сказать на лету.

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

То есть, ключ будет один для двух мепов, а в значение вствалять разные значения через разделитель?
Хм..а если ключ сделать общий, а в значение вставлять контейнер, в котором будут все поля, разделены через разделитель какой-нибудь, тогда мап будет один...и останется придумать, как выдернуть нужное значение из этого мапа. Неплохая идея! Подумаю!
Старый 24.10.2013, 12:30   #28  
plumbum is offline
plumbum
Участник
Соотечественники
 
182 / 86 (3) ++++
Регистрация: 07.12.2007
Адрес: Vienna, AT
Создайте мап такого типа:
X++:
new Map(Types::container, Types::container);
а ключ формируйте таким образом:
X++:
[TableId, keyStr]
или вообще что хотите.

Вся прелесть в том, что Вам нет необходимости знать, сколько полей упаковано в контейнер, до начала обработки. А во время обработки Вы можете в зависимости от TableId из ключа вызвать нужный обработчик
__________________
http://www.axdevposts.blogspot.com
Пришел, уведел.... отойди, дай другому увидеть!
Старый 24.10.2013, 12:30   #29  
LeonDerCom is offline
LeonDerCom
Участник
 
45 / 20 (1) +++
Регистрация: 08.10.2012
Если Вашим кодом, то например так...
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]);
        }

    }
Поскольку ключ таблицы позаботится об уникальности ключа между таблицами, а чтобы вытаскивать данные, можно хоть контейнером ключ сделать, можно в ключь впереди вписать хоть 1 (L) или 2 (I) (сортирует их и доставай сначала одни данные, потом другие), выделять из ключа номер таблицы.

Последний раз редактировалось LeonDerCom; 24.10.2013 в 12:43.
За это сообщение автора поблагодарили: user_ax (1).
Старый 24.10.2013, 12:32   #30  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Цитата:
Сообщение от 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  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
LeonDerCom, да, я так и сделал! Спасибо за ваш пример!
Старый 24.10.2013, 12:46   #32  
LeonDerCom is offline
LeonDerCom
Участник
 
45 / 20 (1) +++
Регистрация: 08.10.2012
user_ax
В таком случае ключик можно уменьшить
listKey = "L#"+list.InternalSp + "#" + list.ItemId;
invoiceKey = "I#"+invoice.InternalSp + "#" + invoice.ItemId;
Старый 24.10.2013, 12:48   #33  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Цитата:
Сообщение от LeonDerCom Посмотреть сообщение
user_ax
В таком случае ключик можно уменьшить
listKey = "L#"+list.InternalSp + "#" + list.ItemId;
invoiceKey = "I#"+invoice.InternalSp + "#" + invoice.ItemId;
Да, вы правы, ключ укоротил.
Теперь буду думать, как в зависимости от ключа доставать нужные данные!
Старый 24.10.2013, 12:50   #34  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Если префикс добавлять в ключ мапа, то значения из разных источников (list и Invoice) не будут складываться между собой. Т.е. грубо говоря, одна и таже номенклатура может оказаться в мапе дважды, с одним префиксом и с другим. Так и нужно?
Старый 24.10.2013, 12:52   #35  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Если префикс добавлять в ключ мапа, то значения из разных источников (list и Invoice) не будут складываться между собой. Т.е. грубо говоря, одна и таже номенклатура может оказаться в мапе дважды, с одним префиксом и с другим. Так и нужно?
А мне и не нужно складвыать значения из двух разных мапов, мне нужно складывать значения в контексте одного мапа.
Да, может оказаться одна и таже номенклатура, просто она будет присутствовать в двух разных таблицах(сейчас у меня так и просиходит).
Старый 24.10.2013, 14:11   #36  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Общий мап сделал с разными ключами, теперь ищу, как за один проход вытаскивать записи с разным ключом(L и V) сразу и загонять данные для обработки.
Старый 24.10.2013, 14:15   #37  
LeonDerCom is offline
LeonDerCom
Участник
 
45 / 20 (1) +++
Регистрация: 08.10.2012
S.Kuskov
С самого начала уже были в ключе ИД таблиц, несмотря на то, что они находились в разных МАПах, то есть в случае слияния МАПов в лоб - данные не должны были пересекаться.

user_ax
MapIterator
X++:
switch (subStr(MapIter.key(),1,1))
{
      case ('L'):

      break;
      case ('V'):

      break;
}
или if else
Или с учетом сортировки 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  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Цитата:
Сообщение от LeonDerCom Посмотреть сообщение
S.Kuskov
С самого начала уже были в ключе ИД таблиц, несмотря на то, что они находились в разных МАПах, то есть в случае слияния МАПов в лоб - данные не должны были пересекаться.
Нет, S.Kuskov прав, записи могли бы повторяться, так как у меня не было уникального значения в ключе, а именно tableid.
Но теперь значения в мепе повторяются по некоторым полям и так и должно быть.
Только теперь пришёл к тому, что надо их разделить по ключам как-то, при этом производить всё это в одном цикле
Я, наверное, уже вас достал...

В данный момент я сделал через 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  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Нужно всё в один цикл получается засунуть.
Старый 24.10.2013, 14:29   #40  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Судя по предыдущему сообщению user_ax соответствующие данные из разных таблиц таки нужно обрабатывать как один элемент
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Помещение временной таблицы в Map Lemming DAX: Программирование 20 19.10.2017 14:16
Dynamics AX: Map Object Sorting - a real issue Blog bot DAX Blogs 7 15.10.2008 12:02
MAP vs Class. В чем идейная необходимость в MAP-ах? А что если использовать Class вместо MAP? Hub DAX: Программирование 16 11.08.2008 16:58
Открытие контейнера из Map tolstjak DAX: Программирование 12 12.11.2006 18:01
Пропадение связи в Map 6apcyk DAX: Программирование 1 08.06.2006 08:05

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 23:06.