1

我最近修改了默认报告 207 Sales Invoice 并创建了一个自定义报告。我的一个请求是在此发票上显示当前发票所涵盖的每批货物的装运信息。特别是我需要显示以下值:

  • 交货单上的装运编号
  • 装运数量

标准报告仅显示发布的装运日期和数量,并且仅显示一次装运(我相信是最后一次装运)。它没有显示“Shipment No.”。

在进行所需的更改时,我遇到了几个问题,并且很难找到有关该findPostedShipmentDate()功能的任何信息,因此我决定在此处发布我的解决方案。

问题是:

  1. 如何在销售发票上显示多批货件?
  2. 如何显示“Shipmente No.” 以及单个数量或每批货物?
4

1 回答 1

1

"Sales Invoice Line"::OnAfterGetRecord()函数findPostedShipmentDate()中调用函数。此函数执行多项检查以查找过帐日期,并在必要时调用GenerateBufferFromValueEntry()填充表“SalesShipmentBuffer”的函数,该表临时存储当前“销售发票行”记录的所有发货信息:

CASE "Sales Invoice Line".Type OF
  "Sales Invoice Line".Type::Item:
    GenerateBufferFromValueEntry("Sales Invoice Line");
  ...

之后,它对缓冲表执行多次检查并再次删除条目(稍后会详细介绍)。

GenerateBufferFromValueEntry下面发生。实际发货信息存储在ItemLedgerEntry(32)表中,为了找到正确的行,使用了ValueEntry(5802)表,其中包含右键(ValueEntry."Item Ledger Entry No.")。

除了现有的范围过滤器之外,我还需要添加一行来将范围限制为 ,Item No.并且我必须删除Entry No.. 我还修改了该功能AddBufferEntry以另外获取ItemLedgerEntry."Document No."包含Shipment No.交货单的内容。这是完整的代码:

TotalQuantity := SalesInvoiceLine2."Quantity (Base)";
ValueEntry.SETCURRENTKEY("Document No.");
ValueEntry.SETRANGE("Document No.",SalesInvoiceLine2."Document No.");
ValueEntry.SETRANGE("Posting Date","Sales Invoice Header"."Posting Date");
ValueEntry.SETRANGE(ValueEntry."Item No.", "Sales Invoice Line"."No."); //Added
ValueEntry.SETRANGE("Item Charge No.",'');
//ValueEntry.SETFILTER("Entry No.",'%1..',FirstValueEntryNo); //Removed
IF ValueEntry.FIND('-') THEN BEGIN
  REPEAT
      IF ItemLedgerEntry.GET(ValueEntry."Item Ledger Entry No.") THEN BEGIN
        IF SalesInvoiceLine2."Qty. per Unit of Measure" <> 0 THEN
          Quantity := ValueEntry."Invoiced Quantity" /
                      SalesInvoiceLine2."Qty. per Unit of Measure"
        ELSE
          Quantity := ValueEntry."Invoiced Quantity";
        AddBufferEntry(
          SalesInvoiceLine2,
          -Quantity,
          ItemLedgerEntry."Posting Date",
          ItemLedgerEntry."Document No."); //Added
        TotalQuantity := TotalQuantity + ValueEntry."Invoiced Quantity";
      END;
    FirstValueEntryNo := ValueEntry."Entry No." + 1;
  UNTIL (ValueEntry.NEXT = 0) OR (TotalQuantity = 0);
END;

在函数中,我还删除了前几行,以防止函数在填充FindPostedShipmentDate之前退出:SalesShipmentBuffer

IF "Sales Invoice Line"."Shipment No." <> '' THEN
  IF SalesShipmentHeader.GET("Sales Invoice Line"."Shipment No.") THEN
    EXIT(SalesShipmentHeader."Posting Date");

IF "Sales Invoice Header"."Order No."='' THEN
  EXIT("Sales Invoice Header"."Posting Date");

在最后一部分FindPostedShipmentDate的记录SalesShipmentBuffer被再次删除,起初可能看起来有点奇怪(对我来说确实如此)。原因是即使在调用DELETEDELETEALL函数之后,记录变量也会保留在调用这些函数之前存储在记录中的值。因此结果是SalesShipmentBuffer表格被清除,以便下次运行该findPostedShipmentDate()函数时为空,但这些值仍然可以在报告中使用。另一个令人困惑的部分是它实际上做了一件非常简单的事情,看起来非常复杂。如果缓冲区仅包含一行,则删除该行,否则如果包含多行,则首先计算所有数量字段的总和,然后删除所有行。

无论如何,我只需要进行一项更改,即删除以下行,因为该Document No.字段现在包含发货编号而不是发票编号。

SalesShipmentBuffer.SETRANGE("Document No.","Sales Invoice Line"."Document No.");

这是剩余的代码:

SalesShipmentBuffer.SETRANGE("Line No." ,"Sales Invoice Line"."Line No.");
SalesShipmentBuffer.SETRANGE("No." ,"Sales Invoice Line"."No.");
IF SalesShipmentBuffer.FIND('-') THEN BEGIN
  SalesShipmentBuffer2 := SalesShipmentBuffer;
    IF SalesShipmentBuffer.NEXT = 0 THEN BEGIN
      SalesShipmentBuffer.GET(
        SalesShipmentBuffer2."Document No.",
        SalesShipmentBuffer2."Line No.",
        SalesShipmentBuffer2."Entry No."
      );
      SalesShipmentBuffer.DELETE;
      EXIT(SalesShipmentBuffer2."Posting Date");
    END ;
   SalesShipmentBuffer.CALCSUMS(Quantity);
   IF SalesShipmentBuffer.Quantity <> "Sales Invoice Line".Quantity THEN BEGIN
     SalesShipmentBuffer.DELETEALL;
     EXIT("Sales Invoice Header"."Posting Date");
   END;
END ELSE
  EXIT("Sales Invoice Header"."Posting Date");

而已。现在我只需要修改 DataItem 源条目以在报告中显示必要的字段。我必须做的更改实际上并没有那么多,但是根本没有记录代码,当我搜索这个问题或涉及的功能时,我找不到太多信息。因此,我希望我的帖子对您​​有所帮助,以防有人遇到与我类似的问题。


另一方面,我不明白为什么上面的代码段是这样写的,为什么,我相信(虽然我还没有验证过),它可以被简化为下面的代码,这更具可读性。如果您觉得我的分析有误,请发表评论。

SalesShipmentBuffer.SETRANGE("Line No." ,"Sales Invoice Line"."Line No.");
SalesShipmentBuffer.SETRANGE("No." ,"Sales Invoice Line"."No.");
SalesShipmentBuffer.FINDFIRST;
IF SalesShipmentBuffer.COUNT > 0 THEN BEGIN
  IF SalesShipmentBuffer.COUNT = 1 THEN BEGIN
    SalesShipmentBuffer.DELETE;
    EXIT(SalesShipmentBuffer2."Posting Date");
  END ELSE BEGIN
    SalesShipmentBuffer.CALCSUMS(Quantity);
    SalesShipmentBuffer.DELETEALL;
    EXIT("Sales Invoice Header"."Posting Date");
  END;
END ELSE
  EXIT("Sales Invoice Header"."Posting Date");
于 2013-09-13T19:37:55.673 回答