Search code examples
sapb1

Business One: cannot seem to display the totals in a matrix


I have implemented a custom form with a matrix in an addon for SAP Business One v. 10.00.150, but cannot cause it to display totals under some of the matrix columns. I have:

static Column AddCol( Cols cols, string id, string title, BoFieldsType type, BoFormItemTypes itype, bool editable )
{   Column mcol;
    // cols.Mx is the SAPbouiCOM.Columns
    mcol = cols.Mx.Add( id, itype );
    mcol.TitleObject.Caption = title;
    cols.Dt.Add( id, type, 254 );
    mcol.DataBind.Bind( DtId, id );
    mcol.Editable = editable;
    if( type == ft_Quantity )
    {   mcol.ColumnSetting.SumType = BoColumnSumType.bst_Auto;  }
    return mcol;
}

The totals row is created in the matrix, but all the values are empty regardless of the matrix contents. What is missing? The matrix is bound to a DataTable datasource and works...

Update

I have localised the error—auto totals work only for the last column in the matrix, at least for me. Please, try the following code with true and false in the condition. If column 2 is added, the totals in column 1 miraculously stop working:

// dt is SAPbouiCOM.DataTable
// mx is SAPbouiCOM.Matrix
Column   col;
dt.Columns.Add( "1", BoFieldsType.ft_Quantity, 0 );
col = mx.Columns.Add( "1", BoFormItemTypes.it_EDIT );
col.TitleObject.Caption = "Should have a total";
col.DataBind.Bind( dt.UniqueID, "1" );
col.ColumnSetting.SumType = BoColumnSumType.bst_Auto;

// If another column follows a column with auto totals, the auto totals
// are not displayed -- try below with false and true:
if( true )
{   dt.Columns.Add( "2", BoFieldsType.ft_AlphaNumeric, 254 );
    col = mx.Columns.Add( "2", BoFormItemTypes.it_EDIT );
    col.TitleObject.Caption = "Breaks auto totals.";
    col.DataBind.Bind( dt.UniqueID, "2" );
}

dt.Rows.Add(2);
dt.SetValue( "1", 0, 1.00 );
dt.SetValue( "1", 1, 0.23 );
mx.LoadFromDataSource();

Solution

  • A workaround

    Thanks to Praxiom's answer, I have found that the bug does not occur if the DataTable is sturctured via .ExecuteQuery. This let me implement the following workaround:

    static void HackStructDt( DataTable dt )
    {   const string QTempl = "SELECT TOP 0 {0} FROM RDR1";
    
        int      i, n;
        ColEntry ce  ;
        string   fields, field, fldspec;
        string   query;
    
        n = ColTab.Count; // my metadata with column specs.
    
        fields = "";
        for( i = 0; i < n; i += 1 )
        {   ce = ColTab[ i ];
            field = "";
            switch( ce.Type )
            {   case ft_AlphaNumeric:
                case ft_Text        : field = "Address"  ; break;
                case ft_Integer     : field = "DocEntry" ; break;
                case ft_ShortNumber : field = "GrossBase"; break;
                case ft_Measure     : field = "Weight1"  ; break;
                case ft_Percent     : field = "VatPrcnt" ; break;
                case ft_Price       : field = "Price"    ; break;
                case ft_Quantity    : field = "Quantity" ; break;
                case ft_Rate        : field = "Rate"     ; break;
                case ft_Sum         : field = "VatSum"   ; break;
                case ft_Date        : field = "ShipDate" ; break;
                case ft_Float       : throw new Exception("Float type is not supported");
            }
            fldspec = field + " AS " + ce.Id;
            if( fields != "" ) fields = fields + ", ";
            fields = fields + fldspec;
        }
        query = Format( QTempl, fields );
        dt.ExecuteQuery( query );
    }