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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 15.05.2012, 12:47   #1  
niksen is offline
niksen
Участник
Самостоятельные клиенты AX
 
284 / 28 (1) +++
Регистрация: 05.07.2011
Адрес: Татарстан
Программный ввод складских остатков
День добрый!
благодаря желанию пользователей, которые хотят что-то проанализировать, вышла следующая задача, которая коротко выглядит следующим образом: поиграться с различными исходами планирования в результате различных складских остатков. Естественно это на отдельной компании, поэтому можно ломать всё что угодно, лишь бы master planning правильно считал и видел новые остатки.
Версия 2009
Итак, складские остатки при работе пользователей как я понимаю, вводятся следующим образом:
1) создаётся журнал с типом "Проводка"
2) создаются и заполняются строки в этом журнале
3) журнал разносится
4) остатки пересчитываются автоматически
Вопрос: как это реализовать программно? Пусть на входе будет таблица типа, в которой будет наименование и код журнала, код номенклатуры, количество, дата, номенклатурные аналитики, вообще всё вобщем, что потребуется для ввода. То есть данные на входе для ввода остатков именно таким образом есть.
Вопрос в том, с какими классами будет правильнее работать и с таблицами ли, так, чтобы избежать подводных камней. (функционал не изменён, чистый стандарт допустим)
Поправьте меня. если я что-то неправильно понял: журнал находится в таблице InventJournalTable, создать можно классом AxInventJournalTable. Сами строки журнала находятся где-то в InventJournalTrans, работать с ней проще через AxInventJournalTrans. А как дальше разнести всё это добро?) Как пересчитать остатки или при разноске это происходит автоматически?
Всё это ооочень интересная тема
Заранее спасибо

p,s. интересно, что будет если вводить также строки с минусовым количеством, для анализа ситуации, когда "о боже, у нас же на складе на 1 штуку меньше, чем нужно".
Старый 15.05.2012, 12:53   #2  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
Цитата:
Сообщение от niksen Посмотреть сообщение
День добрый!
благодаря желанию А как дальше разнести всё это добро?) Как пересчитать остатки или при разноске это происходит автоматически?
X++:
InventJournalCheckPost::newPostJournal(inventJournalTable).run();
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
За это сообщение автора поблагодарили: niksen (1).
Старый 15.05.2012, 13:01   #3  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от niksen Посмотреть сообщение
лишь бы master planning правильно считал и видел новые остатки
Сводное планирование может учитывать и неразнесённые приходы/расходы
За это сообщение автора поблагодарили: niksen (1).
Старый 15.05.2012, 13:07   #4  
Vals is offline
Vals
Аманд
Аватар для Vals
Компания АМАНД
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2009
 
1,766 / 507 (20) +++++++
Регистрация: 27.02.2002
Адрес: Pass partout, Москва
А можно так:
1. Создать Новый Сводный план (отключить учёт проводок и наличия), включить прогнозный план.
2. Создать Прогнозный план (Продажи, Закупки, Остатки)
3. Связать Новый план с прогнозным планом, выполнить планирование.

Это можно делать на рабочей системе и затем сравнить результаты рабочего и расчётного плана.
За это сообщение автора поблагодарили: S.Kuskov (2), niksen (1).
Старый 15.05.2012, 14:19   #5  
BOAL is offline
BOAL
Участник
Аватар для BOAL
MCBMSS
Злыдни
1C
Лучший по профессии 2015
 
621 / 453 (17) +++++++
Регистрация: 28.04.2003
Адрес: Москва
Закачка строк складского журнала (СЖ) из Ехеля штатно (через шаблон по таблице) возможна, но ничего толком не даст, тк в момент инсерта строк должны делаться складские проводки + есть связанная таблица аналитик, которую в одной "простыне" Ехели заполнять неудобно.

Поэтому у нас уже оч много лет (с первого внедрения АХ) реализован импорт СЖ из Ехель.

И вот им уже заливается нужный набор начальных данных по номенклатуре.
За это сообщение автора поблагодарили: niksen (1).
Старый 15.05.2012, 16:25   #6  
niksen is offline
niksen
Участник
Самостоятельные клиенты AX
 
284 / 28 (1) +++
Регистрация: 05.07.2011
Адрес: Татарстан
Цитата:
Сообщение от BOAL Посмотреть сообщение
Закачка строк складского журнала (СЖ) из Ехеля штатно (через шаблон по таблице) возможна, но ничего толком не даст, тк в момент инсерта строк должны делаться складские проводки + есть связанная таблица аналитик, которую в одной "простыне" Ехели заполнять неудобно.

Поэтому у нас уже оч много лет (с первого внедрения АХ) реализован импорт СЖ из Ехель.

И вот им уже заливается нужный набор начальных данных по номенклатуре.
именно это и хочу сделать. Загрузка складских остатков для экспериментов, чтобы удобно загрузив данные можно было с ними играть как хочешь. Например, указать даже в этом файле не то, чтобы количество, на которое нужно изменить, а количество, которое было прогнозируемым на начало месяца, а потом сравнить, как рассчитался бы план с учётом этого.
Если же создавать журнал и не разносить его в рабочей базе, можно получить много проблем, ведь в данный момент в ней работают и неправильный рассчёт будет очень некстати.
Если использовать прогнозный план и т.д. - нужно опять-таки использовать огромное количество всякого функционала, который нужно дополнительно настраивать и ему же обучать, на это нет сил и времени. А вот написать небольшой импорт для отдельной базы чтобы с ней иногда играть и делать какие-то выводы - это самое то. И другим не мешают. И сами делают, что хотят, - набили файл в экселе с нужным количеством, загрузили его, посчитали, удалили и всё ок.
Старый 16.05.2012, 07:25   #7  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от niksen Посмотреть сообщение
использовать огромное количество всякого функционала, который нужно дополнительно настраивать и ему же обучать, на это нет сил и времени.

Цитата:
Человек, идущий через лес, и наблюдающий как мужик старательно рубит дерево тупым топором, обращается к нему:
- Мужик, ты бы топор заточил.
Мужик:
- Да некогда мне – я дерево рублю.
Старый 16.05.2012, 10:18   #8  
niksen is offline
niksen
Участник
Самостоятельные клиенты AX
 
284 / 28 (1) +++
Регистрация: 05.07.2011
Адрес: Татарстан
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
именно так
Россия же как начальство скажет, так и сделаем зарплату то все хотят заодно изучим положение под названием "в жопе", а то так ведь никто и не оценит положения "всё в шоколаде"
Старый 16.05.2012, 11:53   #9  
niksen is offline
niksen
Участник
Самостоятельные клиенты AX
 
284 / 28 (1) +++
Регистрация: 05.07.2011
Адрес: Татарстан
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Сводное планирование может учитывать и неразнесённые приходы/расходы
предлагаете заносить их, но не разносить?
Старый 16.05.2012, 12:23   #10  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от niksen Посмотреть сообщение
предлагаете заносить их, но не разносить?
Для планирования разницы никакой
Конечно если складские проводки включены в настройках сводного
Старый 16.05.2012, 13:37   #11  
YuraK is offline
YuraK
Участник
NavAx Club
 
9 / 10 (1) +
Регистрация: 16.08.2005
Пример создания складского журнала. Хотя присоединяюсь к вышесказанному, экспериментировать со сводным планированием (для получения результата) стоит с наличием 5-10 операций по одной номенклатур, котрые можно создать и руками.
Вложения
Тип файла: xpo Job_CopyOfarn_yura_createJournal.xpo (9.7 Кб, 190 просмотров)
Старый 16.05.2012, 14:05   #12  
niksen is offline
niksen
Участник
Самостоятельные клиенты AX
 
284 / 28 (1) +++
Регистрация: 05.07.2011
Адрес: Татарстан
Цитата:
Сообщение от YuraK Посмотреть сообщение
Пример создания складского журнала. Хотя присоединяюсь к вышесказанному, экспериментировать со сводным планированием (для получения результата) стоит с наличием 5-10 операций по одной номенклатур, котрые можно создать и руками.
к сожалению не нашёл в ней следующего типа ARN_RestMaterialFor2009
я немного по-другому сделал, попозже выложу
Старый 21.05.2012, 16:14   #13  
niksen is offline
niksen
Участник
Самостоятельные клиенты AX
 
284 / 28 (1) +++
Регистрация: 05.07.2011
Адрес: Татарстан
X++:
void TmpTableToDBTable()
{
    timeofday                   timeCounter;
    str 20                      JournalId;
    InventLocation              InventLocation;
    InventLocationId            InventLocationId;
    InventDim                   InventDim;
    InventDimId                 InventDimId;
    int                         cnt;
    InventSite                  InventSite;
    InventSiteId                SiteId;
    InventTrans                 InventTrans;
    InventTransId               InventTransId;
    ;
    updated = 0;
    created = 0;
    info(time2str(timenow(),1,1) + ' начало загрузки в рабочую БД');
    timeCounter = timenow();
    journalid = '000101_131';
    delete_from InventJournalTrans
        where InventJournalTrans.JournalId == journalId;
    //journalId = strfmt(time2str(timenow(),1,1)+'начдан');
    select firstonly InventLocation
        where InventLocation.InventLocationType == InventLocationType::Standard;
        {
         InventLocationId = InventLocation.InventLocationId;
         ///  первый попавшийся склад
        }
    select firstonly InventSite;
        {
         SiteId = InventSite.SiteId;
         /// первый попавшийся сайт
        }

    info('выбран склад');
    ttsbegin;
    while select forupdate DAXInventItem
        {
            inventDim = null;
            inventDim.InventLocationId  = InventLocationId;
            inventDim.InventSiteId = SiteId;
            inventDim = InventDim::findOrCreate(inventDim);
            DAXInventItem.inventDimId   = inventDim.inventDimId;
            DAXInventItem.update();
        }
    ttscommit;
    info('обновлена аналитика');

    ttsbegin;
    if (InventJournalTable::exist(journalId))
    {
        info('журнал найден');
    }
    else
    {
    /// создание журнала
    select forupdate firstonly InventJournalTable
        where InventJournalTable.JournalId == journalId;
        {
            ++created;
            AxInventJournalTable = AxInventJournalTable::construct();
            AxInventJournalTable.inventJournalTable(InventJournalTable);
            AxInventJournalTable.parmJournalId(journalId);
            AxInventJournalTable.parmJournalType(InventJournalType::Movement);
            AxInventJournalTable.parmPosted(NoYes::No);
            AxInventJournalTable.parmReservation(ItemReservation::None);
            AxInventJournalTable.parmSystemBlocked(NoYes::No);
            AxInventJournalTable.parmVoucherDraw(JournalVoucherDraw::Entering);
            AxInventJournalTable.parmVoucherChange(InventJournalVoucherChange::DateChange);
            AxInventJournalTable.parmDeletePostedLines(NoYes::No);
            AxInventJournalTable.parmDetailSummary(DetailSummary::Detail);
            AxInventJournalTable.parmJournalNameId('ЖурПр.');
            AxInventJournalTable.save();
            InventJournalTable = AxInventJournalTable.inventJournalTable();
            InventJournalTable.update();
        }
        info('создан журнал');
    }
    ttscommit;
    cnt = 0;
    ttsbegin;
    while select DAXInventItem
    {
      select forupdate InventJournalTrans
        where InventJournalTrans.JournalId == journalId  &&
                InventJournalTrans.ItemId == DAXInventItem.ItemId &&
                InventJournalTrans.Qty == DAXInventItem.Qty &&
                InventJournalTrans.TransDate == DAXInventItem.TransDate;
        {
            ++created;
            ++cnt;
            InventJournalTrans.initValue();
            InventJournalTrans.InventDimId= DAXInventItem.InventDimId;
            InventJournalTrans.ItemId = DAXInventItem.ItemId;
            InventJournalTrans.Qty = DAXInventItem.Qty;
            InventJournalTrans.TransDate = DAXInventItem.TransDate;
            InventJournalTrans.JournalType = InventJournalType::Movement;
            InventJournalTrans.PriceUnit = 1.00;
            InventJournalTrans.LineNum = InventJournalTrans::lastLineNum(journalId)+1;
            InventJournalTrans.CostPrice = 0.00;
            InventJournalTrans.CostAmount =0.00;
            InventJournalTrans.CostMarkup = 0.00;
            InventJournalTrans.SalesAmount = 0.00;
            InventJournalTrans.LedgerAccountIdOffset = "Корр.Счёт";
            InventJournalTrans.BOMLine = NoYes::No;
            InventJournalTrans.AssetTransType = AssetTransTypeJournal::None;
            InventJournalTrans.Voucher = '';
            InventJournalTrans.JournalId = journalId;
            InventJournalTrans.CostPrice = 0.00;
            InventJournalTrans.PriceUnit = 1.00;
            InventJournalTrans.CostMarkup = 0.00;
            InventJournalTrans.CostAmount = 0.00;
            InventJournalTrans.SalesAmount = 0.00;
            InventJournalTrans.ProjTransId = "";
            InventJournalTrans.InventTransId = int2str(00027231+cnt+1)+'_129';
            InventJournalTrans.InventTransIdFather = '';
            InventJournalTrans.InventOnHand = 0.00;
            InventJournalTrans.Counted = 0.00;
            InventJournalTrans.Dimension[1] = "";
            InventJournalTrans.Dimension[2] = "";
            InventJournalTrans.Dimension[3] = "";
            InventJournalTrans.InventTransIdReturn = "";
            InventJournalTrans.ProjCategoryId = "";
            InventJournalTrans.ProjId = "";
            InventJournalTrans.DEL_CorrectedInvoiceId = "";
            InventJournalTrans.ToInventTransId = "";
            InventJournalTrans.ReasonRefRecId = 0;
            InventJournalTrans.ToInventDimId = "";
            InventJournalTrans.ReqPOId = "";
            InventJournalTrans.EmplId = "";
            InventJournalTrans.AssetTransType = AssetTransTypeJournal::None;
            InventJournalTrans.AssetId = "";
            InventJournalTrans.AssetBookId = "";
            InventJournalTrans.ProjTaxGroupId = "";
            InventJournalTrans.ProjSalesCurrencyId = "";
            InventJournalTrans.ProjLinePropertyId = "";
            InventJournalTrans.ProjTaxItemGroupId = "";
            InventJournalTrans.ProjUnitID = "";
            InventJournalTrans.ProjSalesPrice = 0.00;
            InventJournalTrans.InventRefType = InventRefType::None;
            InventJournalTrans.InventRefId = "";
            InventJournalTrans.InventRefTransId = "";
            InventJournalTrans.ProfitSet = CostProfitSet::Standard;
            InventJournalTrans.ActivityNumber = "";
            InventJournalTrans.Storno_RU = NoYes::No;
            InventJournalTrans.ServiceTariffId_PL = "";
            InventJournalTrans.ScrapTypeId_RU = "";
            InventJournalTrans.write();
        }
    }
    ttscommit;

     info('создано записей ' + int2str(created));
     info('обновлено записей ' + int2str(updated));
     info(time2str(timenow(),1,1) + ' конец загрузки в рабочую БД');
     timeCounter = timenow()-timeCounter;
     info('времени загрузки в основную БД '+time2str(timeCounter,1,1));

}
вот примерно это получилось
используется одна временная таблица, в которой аналитика проставляется исходя из 1 сайта и склада, можете указать нужный сайт и склад, дело ваше
Косяк конечно у меня с transId, если кто подскажет, исправить, буду рад
p.s. этот код загружает данные, но не разносит журнал. Разносил я вручную, т.к. мне нравится контролировать процесс
Старый 21.05.2012, 16:31   #14  
michel1971 is offline
michel1971
Участник
 
78 / 78 (3) ++++
Регистрация: 14.01.2011
зачем велосипед изобретать.
2009 под рукой нет, есть 3.0, так вот в ней есть \Classes\TutorialJournalCreateExample и в нем метод создания журнла

X++:
TutorialJournalTable        journalTable;
    TutorialJournalTrans        journalTrans;

    TutorialJournalTableData    journalTableData  = JournalTableData::newTable(journalTable);
    TutorialJournalTransData    journalTransData  = journalTableData.JournalStatic().newJournalTransData(journalTrans,journalTableData);

    Integer                     x;
    ;

    // Init journalTable

    journalTable.journalId      = journalTableData.nextJournalId();
    journalTable.journalType    = InventJournalType::Movement;
    journalTable.journalNameId  = journalTableData.JournalStatic().standardJournalNameId(journalTable.journalType);

    journalTableData.initFromJournalName(journalTableData.JournalStatic().findJournalName(journalTable.journalNameId));

    // OR
    //
    // journalTable.initFromJournalName(TutorialJournalName::find(journalTable.journalNameId));

    // Loop lines

    for (x = 1; x <= 15; x++)
    {
        journalTrans.clear();
        journalTransData.initFromJournalTable();

        journalTrans.transDate      = systemdateGet() + x div 2;
        journalTrans.exItemId       = (select firstOnly inventTable).itemId;
        journalTrans.exCostAmount   = x;

        journalTransData.create();
    }

    journalTable.insert();
как разносить Lev Вам написал
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Ввод начальных остатков по клиентам и поставщикам Akri DAX: Функционал 12 26.01.2012 10:59
ввод начальных остатков АКС DAX: Функционал 36 28.11.2011 15:04
Ввод остатков по счету 14 (резерв под снижение стоимости ТМЦ) Dolores DAX: Функционал 13 28.10.2011 15:59
Статья о новом механизме блокировок складских остатков в Ax 4.0 lev DAX: Программирование 3 01.06.2011 10:56
ввод остатков по ОС lana DAX: Функционал 1 07.04.2004 18:17

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

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

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