【问题标题】:Updating custom field is ending into infinite loop更新自定义字段将进入无限循环
【发布时间】:2018-09-14 22:58:06
【问题描述】:

我在 AR 发票和备忘录(屏幕 ID AR301000)中有一个自定义字段,用于对应 AP Ref。编号。在类似的管理器中,对应 AR Ref 的 AP 账单和调整(屏幕 ID AP301000)中的另一个自定义字段。编号。

我正在尝试更新 AP Ref。编号。当用户更新 AR Ref 时,在 AR 屏幕上。编号。在 AP 屏幕中。

例如-

我在 AR Screen Invoice 0001 上,我正在更新 AP Ref。编号。到 abc01。系统将使用相应的 AR Ref 自动更新 AP Bill abc01。编号。带 0001。

我编写了下面的代码来实现这一点,但它会陷入无限循环,因为它都试图更新其他屏幕中的相应字段。如果我遗漏了什么或者有更好的方法,请告诉我。

关于 AR Graph 扩展

public class ARInvoiceEntryExtension : PXGraphExtension<ARInvoiceEntry>
{
	protected virtual void ARInvoice_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
	{
		var row = (ARInvoice)e.Row;
		if (row != null && sender.IsDirty)
		{
			ARRegisterExtension ext = PXCache<ARRegister>.GetExtension<ARRegisterExtension>(row);

			if (ext != null && !string.IsNullOrEmpty(ext.UsrAPRefNbr))
			{
				APInvoiceEntry graph = PXGraph.CreateInstance<APInvoiceEntry>();

				APInvoice apRow = PXSelect<APInvoice,
					Where<APInvoice.refNbr, Equal<Required<APInvoice.refNbr>>>>.Select(graph, ext.UsrAPRefNbr);

				if (apRow != null)
				{
					APRegisterExtension ext1 = PXCache<APRegister>.GetExtension<APRegisterExtension>(apRow);
					if (ext1 != null && string.IsNullOrEmpty(ext1.UsrARRefNbr))        //Update only if it is empty
					{
						ext1.UsrARRefNbr = row.RefNbr;

						graph.Document.Current = apRow;

						graph.Caches[typeof(APRegister)].SetValue<APRegisterExtension.usrARRefNbr>(apRow, row.RefNbr);
						graph.Caches[typeof(APRegister)].Update(apRow);
						graph.Actions.PressSave();
					}
				}
			}
		}
	}
}

关于 AP Graph 扩展

public class APInvoiceEntryExtension : PXGraphExtension<APInvoiceEntry>
{
	protected virtual void APInvoice_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
	{
		var row = (APInvoice)e.Row;
		if (row != null && sender.IsDirty)
		{
			APRegisterExtension ext = PXCache<APRegister>.GetExtension<APRegisterExtension>(row);

			if (ext != null && !string.IsNullOrEmpty(ext.UsrARRefNbr))
			{
				ARInvoiceEntry graph = PXGraph.CreateInstance<ARInvoiceEntry>();

				ARInvoice arRow = PXSelect<ARInvoice,
					Where<ARInvoice.refNbr, Equal<Required<ARInvoice.refNbr>>>>.Select(graph, ext.UsrARRefNbr);

				if (arRow != null)
				{
					ARRegisterExtension ext1 = PXCache<ARRegister>.GetExtension<ARRegisterExtension>(arRow);
					if (ext1 != null && string.IsNullOrEmpty(ext1.UsrAPRefNbr))        //Update only if it is empty
					{
						ext1.UsrAPRefNbr = row.RefNbr;

						graph.Document.Current = arRow;

						graph.Caches[typeof(ARRegister)].SetValue<ARRegisterExtension.usrAPRefNbr>(arRow, row.RefNbr);
						graph.Caches[typeof(ARRegister)].Update(arRow);
						graph.Actions.PressSave();
					}
				}
			}
		}
	}
}

AR 缓存扩展

public class ARRegisterExtension : PXCacheExtension<ARRegister>
{
	public abstract class usrAPRefNbr : PX.Data.IBqlField
	{
	}

	protected string _usrAPRefNbr;

	[PXDBString(15)]
	[PXUIField(DisplayName = "AP Ref Nbr.", Visibility = PXUIVisibility.SelectorVisible)]

	[APInvoiceType.RefNbr(typeof(Search3<PX.Objects.AP.Standalone.APRegisterAlias.refNbr,
	InnerJoinSingleTable<APInvoice, On<APInvoice.docType, Equal<PX.Objects.AP.Standalone.APRegisterAlias.docType>,
		And<APInvoice.refNbr, Equal<PX.Objects.AP.Standalone.APRegisterAlias.refNbr>>>,
	InnerJoinSingleTable<Vendor, On<PX.Objects.AP.Standalone.APRegisterAlias.vendorID, Equal<Vendor.bAccountID>>>>,
	OrderBy<Desc<APRegister.refNbr>>>))]
	public virtual string UsrAPRefNbr
	{
		get; set;
	}
}

AP 缓存扩展

public class APRegisterExtension : PXCacheExtension<APRegister>
{
	public abstract class usrARRefNbr : PX.Data.IBqlField
	{
	}

	protected string _usrARRefNbr;

	[PXDBString(15)]
	[PXUIField(DisplayName = "AR Ref Nbr.", Visibility = PXUIVisibility.SelectorVisible)]

	[ARInvoiceType.RefNbr(typeof(Search3<PX.Objects.AR.Standalone.ARRegisterAlias.refNbr,
	InnerJoinSingleTable<ARInvoice, On<ARInvoice.docType, Equal<PX.Objects.AR.Standalone.ARRegisterAlias.docType>,
		And<ARInvoice.refNbr, Equal<PX.Objects.AR.Standalone.ARRegisterAlias.refNbr>>>,
	InnerJoinSingleTable<Customer, On<PX.Objects.AR.Standalone.ARRegisterAlias.customerID, Equal<Customer.bAccountID>>>>,
	OrderBy<Desc<ARRegister.refNbr>>>))]
	public virtual string UsrARRefNbr
	{
		get; set;
	}
}

【问题讨论】:

  • 您是否尝试调用 Persist() 而不是调用 PressSave() ?
  • 我调试过,它甚至没有到达那条线。它只是来自更新(上面的行)正在调用另一个方法并结束循环。
  • 我认为 HB_ACUMATICA 在他下面的回复中提供了这个问题的解决方案。

标签: acumatica


【解决方案1】:

保存时,APInvoice_RowUpdated 会修改 ARInvoice,而 ARInvoice 又会修改 APInvoice,从而触发 APInvoice_RowUpdated,从而产生无限循环的事件调用。更新 APInvoice 的 ARInvoice_RowUpdated 中的逆操作将导致类似的无限循环。

要摆脱这种情况,您可以在实例化图形后在运行时删除图形事件处理程序。首先将您的事件处理程序访问修饰符设为公开,以便您可以引用它们:

public virtual void APInvoice_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e) 

创建图表后,获取扩展并移除导致无限循环的处理程序:

APInvoiceEntry graph = PXGraph.CreateInstance<APInvoiceEntry>();
APInvoiceEntryExtension graphExt = graph.GetExtension<APInvoiceEntryExtension>();
graphExt.RowUpdated.RemoveHandler<APInvoice>(graphExt.APInvoice_RowUpdated);

必须对 ARInvoice 进行相同的修改,因为无限循环是双向的,从 AP 到 AR 以及从 AR 到 AP。

【讨论】:

  • Removing RowUpdated Handler 已经起作用并打破了循环。谢谢HB_ACUMATICA
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 2016-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-12
相关资源
最近更新 更多