Acumatica - 复制最后一行

Posted

技术标签:

【中文标题】Acumatica - 复制最后一行【英文标题】:Acumatica - Copy last row 【发布时间】:2018-06-03 15:09:08 【问题描述】:

因此,在 Acumatica 中看似简单的事情实施起来却非常复杂。我想做的就是将网格的最后一行复制为新的。我希望用户自己保留更改,因此我的代码会将其放在缓存中。这是我目前的行动:

    public PXAction<SOOrder> copyLastRow;
    [PXUIField(DisplayName = "Copy Last Row", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
    [PXLookupButton]
    public virtual IEnumerable CopyLastRow(PXAdapter adapter)
    
        SOLine line = Base.Transactions.Select().LastOrDefault();
        int? lineNbr = 0;

        foreach(SOLine line2 in Base.Transactions.Select())            
            if (line2.LineNbr > lineNbr)
                lineNbr = line2.LineNbr;



        line.LineNbr = lineNbr + 1;
        Base.Transactions.Cache.Insert(line);           

        return adapter.Get();
    

所以也许我的代码没有得到什么或完全错误,但无论我做什么都会出错。我的行没有刷新网格,并且我不断收到各种错误,例如“无法保存此记录”或“另一个进程更新了此记录”等。此外,关于如何生成新 lineNbr 的任何想法我有笨拙的逻辑吗?如果有人可以提供帮助,我们将不胜感激。

【问题讨论】:

Acumatica 平台类似于 4GL 编程语言。这些系统使困难的事情变得简单而使简单的事情变得困难是很常见的。这个想法是通过不必重新实现更高级别的系统(如 ORM、并发性、安全性、报告、数据库脚本等)来补偿在小细节上浪费的时间。我建议您根据平台标准模板和最佳模板定制您的设计实践,通过阅读 T100-T200-T300 培训材料,您将更好地了解所有内容是如何组合在一起的。 【参考方案1】:

如果您只想获取该行并复制所有值,您可以使用缓存副本并将 lineid 设为空。然后在插入复制的行时,它会自动获得下一个 linenbr...在您的问题中添加示例代码...

SOLine line = Base.Transactions.Select().LastOrDefault();
var copy = (SOLine)Base.Transactions.Cache.CreateCopy(line);
copy.LineNbr = null;
Base.Transactions.Cache.Insert(copy);

如果新字段或自定义添加到 SOLine 中,此方法也应该是升级友好的,它们将继续被复制,而不必选择性地包括所有要复制的字段(使用 CreateCopy)。

【讨论】:

效果很好!非常感谢!此外,我还可以让用户自救。 完美。我总是尝试让用户进行持久化,除非与某些长时间运行的进程相关的绝对必要。操作按钮在相同的图表/记录上执行更改,我让用户进行保存。【参考方案2】:

代码应该是这样的:

public PXAction<SOOrder> copyLastRow;
[PXUIField(DisplayName = "Copy Last Row", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
[PXProcessButton]
public virtual IEnumerable CopyLastRow(PXAdapter adapter)

    SOLine line = Base.Transactions.Select().LastOrDefault();
    SOLine newLine = new SOLine();
    ... (copy all you need from line to newLine)
    Base.Transactions.Cache.Insert(newLine);           
    Base.Actions.PressSave();
    return adapter.Get();
 

【讨论】:

Ilya,PressSave 不会将更改保留到 db 吗?我希望用户自己这样做,即按保存按钮。还有lineNbr呢?我应该把它留空还是像我发布的代码一样自己生成它。谢谢, 在 GUI 中按“保存”以保存行更改的操作将不起作用 - 不同的线程。您需要在操作中按“保存”,或在 GUI 中复制并保存。 LineNbr 将自动生成。您可以看到为 SOLine DAC 声明的以下 C# 属性: [PXLineNbr(typeof(SOOrder.lineCntr))] 始终注意指定了哪些 C# 属性 - Acumatica 中的很多事情都是由 C# 属性中的逻辑完成的。跨度> 我个人会避免在这种情况下坚持/按保存。只需让用户在准备好后单击保存按钮。解决这个问题应该没有必要。 @Brendan 这就是我想要实现的理想目标,但根据 Illya 所说,这可能是不可能的 @IlyaKalmykov 感谢您的贡献。我将 Brendan 的答案标记为最正确【参考方案3】:

我猜测行号会自动生成!反正它不是按顺序排列的。

我建议您创建一个新的 SOline 行并将可输入字段从所选行(最后一行)转移到同一行并插入。应该可以。

【讨论】:

是的,OP 应该避免复制像 LineNumber 这样的关键字段。这就是导致错误的原因:“另一个进程更新了这条记录”。【参考方案4】:

如果您不想复制附件或注释,请务必添加

copy.NoteID = null;

【讨论】:

以上是关于Acumatica - 复制最后一行的主要内容,如果未能解决你的问题,请参考以下文章

使用 BASIC 在 LibreOffice 中复制表格的最后一行

VBA复制最后一行范围并粘贴到另一个工作表

Acumatica:触发器在另一个自定义按钮上保存验证

IAR常用快捷键和使用小技巧

为啥我的代码的最后一行没有打印?另外,我将数字四舍五入到小数点后两位的最简单方法是啥? [复制]

利用vba怎样编写将工作表中第三行到最后一行(不确定)的数据复制并插入到另一个工作表的第二行前?