Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过基于SOAP合约的API将数千条记录导入Acumatica_Acumatica_Acumatica Kb - Fatal编程技术网

通过基于SOAP合约的API将数千条记录导入Acumatica

通过基于SOAP合约的API将数千条记录导入Acumatica,acumatica,acumatica-kb,Acumatica,Acumatica Kb,我正在使用基于合同的SOAP API尝试将大约25000个日记账分录行从银行系统导入到单个Acumatica GL批处理中 如果我尝试将所有记录同时添加到同一总账批次,我的 请求在几个小时后超时。因为它使用相同的GL 批处理,此解决方案不利用多线程 我还尝试将25000行一行一行地添加到 单个总账批处理和请求不会超时,但 之后,性能速度开始显著降低 大约有3000条记录添加到总账批次中。这 该过程需要几个小时才能运行,因为它使用相同的总账 批处理,此解决方案不利用多线程 我还研究了多线程,以便将

我正在使用基于合同的SOAP API尝试将大约25000个日记账分录行从银行系统导入到单个Acumatica GL批处理中

  • 如果我尝试将所有记录同时添加到同一总账批次,我的 请求在几个小时后超时。因为它使用相同的GL 批处理,此解决方案不利用多线程

  • 我还尝试将25000行一行一行地添加到 单个总账批处理和请求不会超时,但 之后,性能速度开始显著降低 大约有3000条记录添加到总账批次中。这 该过程需要几个小时才能运行,因为它使用相同的总账 批处理,此解决方案不利用多线程

  • 我还研究了多线程,以便将数据导入到 几个较小的GL批次,每个批次有5000条生产线,无需 任何超时问题。但仍然需要大约一个半小时才能完成 跑此外,客户不接受这种多批次方法; 他们希望所有的日常数据都在一个总账批次中

  • 25000条记录对我来说并不多,所以我想知道Acumatica的API是否不是在一次交易中为这一数量的行构建的。我在代码中所做的就是通过读取一个文本文件,然后调用put方法来创建包含25000行记录的实体的GL批处理,从而构建实体信息

    我读过几篇关于优化API的文章,但它们主要处理实体的不同实例,例如在几个不同的GL批次或几个不同的库存项目中。在这些情况下,多线程是一个很好的资产,因为您可以让多个线程创建多个“不同”的总账批次,但多线程在更新同一总账批次时没有帮助

    以下是我到目前为止读到的内容:

    我在这里不知所措,所以任何指点都将不胜感激

    我期待你的答复

    这是我的密码:

        public static void CreateMultipleLinesPerJournalEntryBatchContractTEST(MyStoreContract.DefaultSoapClient soapClient, List<JournalEntry> journalEntries)
        {
            string myModuleForBatchLookup = "GL";
    
            //list holding the values of all the records belonging to the batch in process
            List<JournalEntry> allBatchItems = journalEntries;
            //List used to store objects in format required by Acumatica
            List<MyStoreContract.JournalTransactionDetail> myJournalTransactionsFormatted = new List<MyStoreContract.JournalTransactionDetail>();
    
            try
            {
    
    
                //Creating a header and returning a batch value to be used for all  line iterations. 
                JournalEntry myHeaderJournalEntryContract = allBatchItems.First();
                string myBatchNumberToProcess = AddGLBatchHeaderContractTEST(soapClient, myHeaderJournalEntryContract);
    
                // Do something with then n number of items defined in processing subBatch size  or remaining items if smaller
                foreach (JournalEntry je in allBatchItems)
                {
                    //Moving the items in each batch from the original unformatted list to the formatted list one at a time 
                    myJournalTransactionsFormatted.Add(new MyStoreContract.JournalTransactionDetail
                    {
                        BranchID = new MyStoreContract.StringValue { Value = je.Branch },
                        Account = new MyStoreContract.StringValue { Value = je.Account },
                        Subaccount = new MyStoreContract.StringValue { Value = je.Subaccount },
                        ReferenceNbr = new MyStoreContract.StringValue { Value = je.RefNumber },
                        DebitAmount = new MyStoreContract.DecimalValue { Value = je.DebitAmount },
                        CreditAmount = new MyStoreContract.DecimalValue { Value = je.CreditAmount },
                        TransactionDescription = new MyStoreContract.StringValue { Value = je.TransactionDescription },
                        UsrTransactionTime = new MyStoreContract.StringValue { Value = je.UsrTransactionTime },
                        UsrTransactionType = new MyStoreContract.StringValue { Value = je.UsrTransactionType },
                        UsrTranSequence = new MyStoreContract.StringValue { Value = je.UsrTranSequence },
                        UsrTellerID = new MyStoreContract.StringValue { Value = je.UsrTellerID }
                    });
                }
    
    
                //Specify the values of a new Jornal Entry using all the collected elements from the batch(list) created 
                MyStoreContract.JournalTransaction journalToBeCreated = new MyStoreContract.JournalTransaction
                {
                    //Header data and details added by list generated by loop
                    BatchNbr = new MyStoreContract.StringSearch { Value = myBatchNumberToProcess }, //This is one of two lines used to lookup/search the batch needing to be updated
                    Module = new MyStoreContract.StringSearch { Value = myModuleForBatchLookup }, //This is one of two lines used to lookup/search the batch needing to be updated
                    Details = myJournalTransactionsFormatted.ToArray() // this is the line adding the array containing all the line details
                };
    
                soapClient.Put(journalToBeCreated);
    
    
                Console.WriteLine("Added " + allBatchItems.Count.ToString() + " line transactions");
                Console.WriteLine();
                Console.WriteLine("Press any key to continue");
                Console.ReadLine();
    
    
    
            }
    
            catch (Exception e)
            {
                Console.WriteLine("The following error was encountered and all entries for this batch need to be logged in error table");
                Console.WriteLine();
                Console.WriteLine(e.Message);
                Console.WriteLine();
                Console.WriteLine("Press any key to continue");
                Console.ReadLine();
            }
    
    
    
    
        }
    
    
        public static string AddGLBatchHeaderContractTEST(MyStoreContract.DefaultSoapClient soapClient, JournalEntry je)
        {
    
            try
            {
    
                //Specify the values of a new Jornal Entry Batch header
                MyStoreContract.JournalTransaction journalToBeCreated = new MyStoreContract.JournalTransaction
                {
                    //Header data
                    BranchID = new MyStoreContract.StringValue { Value = "PRODWHOLE" }, //This is the default branch
                    TransactionDate = new MyStoreContract.DateTimeValue { Value = je.TransactionDate.AddDays(-1) }, //Reduced 1 day from the batch
                    CurrencyID = new MyStoreContract.StringValue { Value = je.CurrencyCode }, //Currency to be used for the batch
                    Description = new MyStoreContract.StringValue { Value = je.TransactionDescription },
                    Hold = new MyStoreContract.BooleanValue { Value = true }
                };
    
                //Create a Journal Entry with the specified values    
    
                MyStoreContract.JournalTransaction newJournalTransaction = (MyStoreContract.JournalTransaction)soapClient.Put(journalToBeCreated);
                string myBatchToProcess = newJournalTransaction.BatchNbr.Value;
    
                return myBatchToProcess;
    
            }
            catch (Exception e)
            {
                Console.WriteLine("Error was caught while trying to create the header for the batch...");
                Console.WriteLine();
                Console.WriteLine(e);
                Console.WriteLine();
    
                return null;
            }
    
    
        }
    
    我尝试了下面描述的Yuriy方法,但是我的自定义字段没有更新。仅更新标准字段。我应该使用哪个命令来更新扩展(自定义)字段。见下面的代码:

                      //Here I create instance of GLTran
                        GLTran row = graph.GLTranModuleBatNbr.Cache.CreateInstance() as GLTran;
    
    
                        //here I get a handle to graph extension GLTranExt to be able to use the added fields.
                        var rowExt = row.GetExtension<GLTranExt>();
    
    
                        row = graph.GLTranModuleBatNbr.Insert(row);
    
                        graph.GLTranModuleBatNbr.Cache.SetValueExt(row, "AccountID", JE.Account);
                        graph.GLTranModuleBatNbr.Cache.SetValueExt(row, "SubID", JE.Subaccount);
                        row.TranDesc = "my line description"; 
                        row.Qty = 1.0m;
                        row.CuryDebitAmt = (JE.DebitAmount);
                        row.CuryCreditAmt = (JE.CreditAmount);
                        rowExt.UsrTellerID = "Test teller";
                        rowExt.UsrTransactionTime = "Test Transaction Time";
                        rowExt.UsrTransactionType = "Test Transaction Type";
                        rowExt.UsrTranSequence = "Test Transaction Sequence";
    
    
    
                        row = graph.GLTranModuleBatNbr.Update(row);
    
                        graph.Actions.PressSave();
    
    //这里我创建了GLTran的实例
    GLTran row=graph.GLTranModuleBatNbr.Cache.CreateInstance()作为GLTran;
    //在这里,我获得了图形扩展GLTranExt的句柄,以便能够使用添加的字段。
    var rowExt=row.GetExtension();
    行=graph.GLTranModuleBatNbr.Insert(行);
    graph.GLTranModuleBatNbr.Cache.SetValueExt(行,“AccountID”,JE.Account);
    graph.GLTranModuleBatNbr.Cache.SetValueExt(行,“子ID”,JE.Subaccount);
    row.TranDesc=“我的线路描述”;
    行数量=1.0m;
    row.CuryDebitAmt=(JE.DebitAmount);
    row.CuryCreditAmt=(JE.CreditAmount);
    rowExt.UsrTellerID=“测试出纳员”;
    rowExt.UsrTransactionTime=“测试事务时间”;
    rowExt.UsrTransactionType=“测试事务类型”;
    rowExt.UsrTranSequence=“测试事务序列”;
    行=graph.GLTranModuleBatNbr.Update(行);
    graph.Actions.PressSave();
    
    在销售订单导入中,我每小时有18000行(4核,32Gb内存)。所以你的25000和我得到的非常相似(一个销售订单有1-6行)。对于您提供的第二个链接,API调用的参数是什么,Acumatica实例的数量是多少(CPU、RAM、SQL Server的参数)

    我建议您考虑缩放AcMICATA,并通过SQL分割来缩放数据库。

    编辑 如果您需要一个带有25000行的GL批次,那么我建议您采用以下解决方法:

  • 再创建一个包含文本框和按钮导入的Acumatica页面
  • 在按钮导入按钮的代码中
    2.1将文本框信息读取为xml(或JSON)
    2.2创建GL图形的实例
    2.3通过图形插入所需金额(在您的情况下为25000行)
    2.4调用图形。按Save()

  • 将Web API您的请求发送到您创建的页面,而不是GL Batch


  • 你好,尤里。这里的问题是,我试图将所有25000条记录放入一个日记账事务中。我有4个内核,16Gb的RAM。我将在上面包含我的代码,以便您可以看到它。不幸的是,我以前从未横向扩展过解决方案,所以我不确定这种方法是否可以在项目的最后期限内学习/测试。另外,由于我对每个批进行一个API调用,扩展是否会有所帮助?请看附录。还可以在skype上添加我:zaletskiy,我会尽量找时间帮助你嗨,Yuriy。我遵循了你的方法,几乎成功了。它适用于标准字段,但不更新自定义字段。请参阅上面添加的更改。我调用“row=graph.GLTranModuleBatNbr.Update(row);”来更新标准字段和graph.Actions.PressSave();为了保存它们,我必须丢失一个更新自定义字段的命令,因为这些字段不起作用,也没有生成任何错误。谢谢您的回复,Yuriy。我发现了问题所在:我使用的命令的顺序/顺序是错误的。我必须先使用“row=graph.GLTranModuleBatNbr.Insert(row);”,然后再使用“var rowExt=row.GetExtension();”。当您插入行时,顺序很重要。如果您按错误的顺序将它们输出,则该行可能具有不同的键。感谢您建议将图形实例化,而不是使用API。这帮助我使用了正确的方法。
                      //Here I create instance of GLTran
                        GLTran row = graph.GLTranModuleBatNbr.Cache.CreateInstance() as GLTran;
    
    
                        //here I get a handle to graph extension GLTranExt to be able to use the added fields.
                        var rowExt = row.GetExtension<GLTranExt>();
    
    
                        row = graph.GLTranModuleBatNbr.Insert(row);
    
                        graph.GLTranModuleBatNbr.Cache.SetValueExt(row, "AccountID", JE.Account);
                        graph.GLTranModuleBatNbr.Cache.SetValueExt(row, "SubID", JE.Subaccount);
                        row.TranDesc = "my line description"; 
                        row.Qty = 1.0m;
                        row.CuryDebitAmt = (JE.DebitAmount);
                        row.CuryCreditAmt = (JE.CreditAmount);
                        rowExt.UsrTellerID = "Test teller";
                        rowExt.UsrTransactionTime = "Test Transaction Time";
                        rowExt.UsrTransactionType = "Test Transaction Type";
                        rowExt.UsrTranSequence = "Test Transaction Sequence";
    
    
    
                        row = graph.GLTranModuleBatNbr.Update(row);
    
                        graph.Actions.PressSave();