Skip to main content
Answer

Automatically Press Select All Based on Selector Filter Value

  • February 3, 2025
  • 3 replies
  • 124 views

Forum|alt.badge.img+2

Hi I have created 2 selectors in material wizard 1 screen (AM300010) as below

If the selector gives one record after putting the production number in the filter it should automatically press the Select All button.

How can I achieve this, I have tried using  Base.Actions["SelectAll"].Press(); but i get the error:

System.NullReferenceException
Message: Object reference not set to an instance of an object.

using System;
using PX.Data;
using System.Collections.Generic;
using PX.Objects.CS;
using System.Collections;
using System.Linq;
using PX.Objects.IN;
using PX.Objects.AM.Attributes;
using PX.Objects;
using PX.Objects.AM;

namespace PX.Objects.AM
{
public class MatlWizard1_Extension : PXGraphExtension<PX.Objects.AM.MatlWizard1>
{
#region Event Handlers

protected void AMProdItem_Selected_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e, PXFieldUpdated baseHandler)
{

baseHandler?.Invoke(cache, e);
var row = (AMProdItem)e.Row;
if (row.Selected == true) // Only if the item is selected
{
//row.QtytoProd = 1.0000m;
//cache.Update(row);
cache.SetValueExt<AMProdItem.qtytoProd>(row, 1.0000m); // Notify Acumatica of the update
}

}

#endregion

#region View Extensions


public override void Initialize()
{
base.Initialize();

Base.OpenOrders.SetProcessDelegate(list =>
{
var filter = Base.filter.Current;
if (filter != null)
{
var filterExt = filter.GetExtension<WizFilterExt>();

// Apply warehouse filter
if (filterExt?.UsrWarehouseSelector2 != null)
{
var warehouseID = filterExt.UsrWarehouseSelector2;
list = list.Where(item => item.SiteID == warehouseID).ToList();
}

// Apply production number filter
if (!string.IsNullOrWhiteSpace(filterExt?.UsrProdOrderNoFilter))
{
list = list.Where(item =>
item.ProdOrdID != null &&
item.ProdOrdID.Trim().Contains(filterExt.UsrProdOrderNoFilter.Trim())
).ToList();
}

// If only one record is found, automatically select it
// if (list.Count == 1)
// {
// Execute the SelectAll action
// Base.selectall.Press();
// foreach (AMProdItem item in list)
// {
// item.Selected = true;
// Base.OpenOrders.Cache.SetValueExt<AMProdItem.qtytoProd>(item, 1.0000m);
// }
// Press the "Select All" button programmatically
// Base.Actions["SelectAll"].Press(); //
// }

}

MatlWizard1.FillMatlWrk(list, filter);
});
}

protected virtual IEnumerable openOrders()
{
var baseView = new PXView(Base, true, Base.OpenOrders.View.BqlSelect);
var startRow = PXView.StartRow;
int totalRows = 0;
var filter = Base.filter.Current;

if (filter == null)
{
return baseView.Select(PXView.Currents, PXView.Parameters,
PXView.Searches, PXView.SortColumns, PXView.Descendings,
PXView.Filters, ref startRow, PXView.MaximumRows, ref totalRows);
}

var filterExt = filter.GetExtension<WizFilterExt>();

// If neither filter is set, return base view
if (filterExt?.UsrWarehouseSelector2 == null &&
string.IsNullOrWhiteSpace(filterExt?.UsrProdOrderNoFilter))
{
return baseView.Select(PXView.Currents, PXView.Parameters,
PXView.Searches, PXView.SortColumns, PXView.Descendings,
PXView.Filters, ref startRow, PXView.MaximumRows, ref totalRows);
}

// Build the where clause based on active filters
BqlCommand cmd = new Select<AMProdItem>();

// Base conditions
cmd = cmd.WhereAnd<Where<AMProdItem.function, NotEqual<OrderTypeFunction.disassemble>,
And<Where<AMProdItem.isOpen, Equal<True>,
And<AMProdItem.completed, NotEqual<True>>>>>>();

// Add warehouse filter if specified
if (filterExt?.UsrWarehouseSelector2 != null)
{
cmd = cmd.WhereAnd<Where<AMProdItem.siteID, Equal<Required<AMProdItem.siteID>>>>();
}

// Add production number filter if specified
if (!string.IsNullOrWhiteSpace(filterExt?.UsrProdOrderNoFilter))
{
cmd = cmd.WhereAnd<Where<AMProdItem.prodOrdID, Like<Required<AMProdItem.prodOrdID>>>>();
}

var view = new PXView(Base, true, cmd);
var parameters = new List<object>();

// Add parameter values in the same order as the where conditions
if (filterExt?.UsrWarehouseSelector2 != null)
{
parameters.Add(filterExt.UsrWarehouseSelector2);
}
if (!string.IsNullOrWhiteSpace(filterExt?.UsrProdOrderNoFilter))
{
parameters.Add("%" + filterExt.UsrProdOrderNoFilter + "%");
}

return view.Select(PXView.Currents, parameters.ToArray(),
PXView.Searches, PXView.SortColumns, PXView.Descendings,
PXView.Filters, ref startRow, PXView.MaximumRows, ref totalRows);

// var result = view.Select(PXView.Currents, parameters.ToArray(),
// PXView.Searches, PXView.SortColumns, PXView.Descendings,
// PXView.Filters, ref startRow, PXView.MaximumRows, ref totalRows);

// If only one record is returned, ensure it's selected

//if (result.Count == 1)
//{
// Base.Actions["SelectAll"].Press();
// }

// return result;

}
#endregion
}
}

Thank you!

Best answer by noorula77

Hi ​@TharidhiP ,

 

Here's how we can modify your code to achieve this safely:

  1. First, let's modify the Initialize() method to handle the selection when exactly one record is found:

public override void Initialize()

{

  base.Initialize();

 

  Base.OpenOrders.SetProcessDelegate(list =>

  {

    var filter = Base.filter.Current;

    if (filter != null)

    {

      var filterExt = filter.GetExtension<WizFilterExt>();

 

      // Apply warehouse filter

      if (filterExt?.UsrWarehouseSelector2 != null)

      {

        var warehouseID = filterExt.UsrWarehouseSelector2;

        list = list.Where(item => item.SiteID == warehouseID).ToList();

      }

 

      // Apply production number filter

      if (!string.IsNullOrWhiteSpace(filterExt?.UsrProdOrderNoFilter))

      {

        list = list.Where(item =>

          item.ProdOrdID != null &&

          item.ProdOrdID.Trim().Contains(filterExt.UsrProdOrderNoFilter.Trim())

        ).ToList();

      }

 

      // If exactly one record is found, select it and set quantity

      if (list.Count == 1)

      {

        foreach (AMProdItem item in list)

        {

          Base.OpenOrders.Cache.SetValue<AMProdItem.selected>(item, true);

          Base.OpenOrders.Cache.SetValue<AMProdItem.qtytoProd>(item, 1.0000m);

          Base.OpenOrders.Cache.Update(item);

        }

      }

    }

 

    MatlWizard1.FillMatlWrk(list, filter);

  });

}

  1. Then, let's modify the method openOrders() to avoid the recursive call:

protected virtual IEnumerable openOrders()

{

  var baseView = new PXView(Base, true, Base.OpenOrders.View.BqlSelect);

  var startRow = PXView.StartRow;

  int totalRows = 0;

  var filter = Base.filter.Current;

 

  if (filter == null)

  {

    return baseView.Select(PXView.Currents, PXView.Parameters,

      PXView.Searches, PXView.SortColumns, PXView.Descendings,

      PXView.Filters, ref startRow, PXView.MaximumRows, ref totalRows);

  }

 

  // ... rest of your existing code ...

 

  var result = view.Select(PXView.Currents, parameters.ToArray(),

    PXView.Searches, PXView.SortColumns, PXView.Descendings,

    PXView.Filters, ref startRow, PXView.MaximumRows, ref totalRows);

 

  return result;

}

 

Key changes made:

  1. Instead of using Base.Actions["SelectAll"].Press(), we directly set the values on the cache using SetValue<>().
    2. We handle the selection logic in the SetProcessDelegate instead of the view delegate to avoid recursive calls.
    3. We use Cache.SetValue<>() instead of Cache.SetValueExt<>() to avoid triggering additional events.
    4. We update the cache after setting both values to ensure the changes are persisted.

 

3 replies

Forum|alt.badge.img+1
  • Jr Varsity III
  • Answer
  • February 6, 2025

Hi ​@TharidhiP ,

 

Here's how we can modify your code to achieve this safely:

  1. First, let's modify the Initialize() method to handle the selection when exactly one record is found:

public override void Initialize()

{

  base.Initialize();

 

  Base.OpenOrders.SetProcessDelegate(list =>

  {

    var filter = Base.filter.Current;

    if (filter != null)

    {

      var filterExt = filter.GetExtension<WizFilterExt>();

 

      // Apply warehouse filter

      if (filterExt?.UsrWarehouseSelector2 != null)

      {

        var warehouseID = filterExt.UsrWarehouseSelector2;

        list = list.Where(item => item.SiteID == warehouseID).ToList();

      }

 

      // Apply production number filter

      if (!string.IsNullOrWhiteSpace(filterExt?.UsrProdOrderNoFilter))

      {

        list = list.Where(item =>

          item.ProdOrdID != null &&

          item.ProdOrdID.Trim().Contains(filterExt.UsrProdOrderNoFilter.Trim())

        ).ToList();

      }

 

      // If exactly one record is found, select it and set quantity

      if (list.Count == 1)

      {

        foreach (AMProdItem item in list)

        {

          Base.OpenOrders.Cache.SetValue<AMProdItem.selected>(item, true);

          Base.OpenOrders.Cache.SetValue<AMProdItem.qtytoProd>(item, 1.0000m);

          Base.OpenOrders.Cache.Update(item);

        }

      }

    }

 

    MatlWizard1.FillMatlWrk(list, filter);

  });

}

  1. Then, let's modify the method openOrders() to avoid the recursive call:

protected virtual IEnumerable openOrders()

{

  var baseView = new PXView(Base, true, Base.OpenOrders.View.BqlSelect);

  var startRow = PXView.StartRow;

  int totalRows = 0;

  var filter = Base.filter.Current;

 

  if (filter == null)

  {

    return baseView.Select(PXView.Currents, PXView.Parameters,

      PXView.Searches, PXView.SortColumns, PXView.Descendings,

      PXView.Filters, ref startRow, PXView.MaximumRows, ref totalRows);

  }

 

  // ... rest of your existing code ...

 

  var result = view.Select(PXView.Currents, parameters.ToArray(),

    PXView.Searches, PXView.SortColumns, PXView.Descendings,

    PXView.Filters, ref startRow, PXView.MaximumRows, ref totalRows);

 

  return result;

}

 

Key changes made:

  1. Instead of using Base.Actions["SelectAll"].Press(), we directly set the values on the cache using SetValue<>().
    2. We handle the selection logic in the SetProcessDelegate instead of the view delegate to avoid recursive calls.
    3. We use Cache.SetValue<>() instead of Cache.SetValueExt<>() to avoid triggering additional events.
    4. We update the cache after setting both values to ensure the changes are persisted.

 


Forum|alt.badge.img+2
  • Author
  • Pro III
  • February 6, 2025

Thank you ​@noorula77 for your suggestion. How can I also ensure the ‘Select All’ button presses automatically when 1 record is filtered after production order number is entered in the selector? The method in relation to this is ProcessAll and calling this within openOrders() causes the recursive calls.

Thanks!


Chris Hackett
Community Manager
Forum|alt.badge.img
  • Acumatica Community Manager
  • May 2, 2025

Hi ​@TharidhiP were you able to find a solution? Thank you!