SVN r808
SVN-Revision: r808
This commit is contained in:
@@ -7021,7 +7021,7 @@ namespace Lskj.Control
|
||||
GridColumnModel GroupPrimary = ColumnList.FirstOrDefault(o => o.IsCustomGroupPrimary);
|
||||
GridColumnModel GroupFieldprimary = ColumnList.FirstOrDefault(o => o.IsCustomGroupField == 1);
|
||||
List<GridColumnModel> GroupField = ColumnList.Where(o => o.IsCustomGroupField == 2).ToList();
|
||||
|
||||
List<GridColumnModel> sumField = ColumnList.Where(o => o.IsCustomGroupField == 3).ToList();
|
||||
if (GroupPrimary == null || GroupFieldprimary == null || !GroupField.Any())
|
||||
return; // 数据不足直接退出
|
||||
|
||||
@@ -7072,7 +7072,7 @@ namespace Lskj.Control
|
||||
var dynamicHeaders = originalDataSource.AsEnumerable()
|
||||
.Select(r => r.Field<string>(GroupFieldprimary.FieldName))
|
||||
.Distinct().Where(x => !string.IsNullOrEmpty(x)).ToList();
|
||||
|
||||
|
||||
// 为每个动态表头生成GridBand,并添加子列
|
||||
foreach (string headerName in dynamicHeaders)
|
||||
{
|
||||
@@ -7111,7 +7111,7 @@ namespace Lskj.Control
|
||||
}
|
||||
bandedGridControlEx.BandedView.EndUpdate();
|
||||
// 构建最终动态数据源
|
||||
DataTable dynamicDataTable = BuildDynamicDataSource(originalDataSource, GroupPrimary, GroupFieldprimary, GroupField, normalColumns, dynamicHeaders);
|
||||
DataTable dynamicDataTable = BuildDynamicDataSource(originalDataSource, GroupPrimary, GroupFieldprimary, GroupField, normalColumns, sumField, dynamicHeaders);
|
||||
bandedGridControlEx.gridControl.DataSource = dynamicDataTable;
|
||||
}
|
||||
|
||||
@@ -7125,98 +7125,75 @@ namespace Lskj.Control
|
||||
/// <param name="normalColumns"></param>
|
||||
/// <param name="dynamicHeaders"></param>
|
||||
/// <returns></returns>
|
||||
private DataTable BuildDynamicDataSource(DataTable originalDataSource,
|
||||
GridColumnModel GroupPrimary,
|
||||
GridColumnModel GroupFieldprimary,
|
||||
List<GridColumnModel> GroupField,
|
||||
List<GridColumnModel> normalColumns,
|
||||
List<string> dynamicHeaders)
|
||||
/// <summary>
|
||||
/// 把行转列、动态列拼接,并对指定列做求和
|
||||
/// </summary>
|
||||
private DataTable BuildDynamicDataSource(
|
||||
DataTable original, // 原始数据
|
||||
GridColumnModel keyCol, // 分组主键
|
||||
GridColumnModel headerCol, // 动态列的“Header”列
|
||||
List<GridColumnModel> subCols, // Header 后要展开的子列
|
||||
List<GridColumnModel> normalCols, // 普通列(取首行值)
|
||||
List<GridColumnModel> sumColumns, // 需要求和的列
|
||||
List<string> headers) // Header 值集合
|
||||
{
|
||||
try
|
||||
var dt = new DataTable();
|
||||
|
||||
/* ============ 1. 建列 ============ */
|
||||
dt.Columns.Add(keyCol.FieldName, original.Columns[keyCol.FieldName].DataType);
|
||||
|
||||
// 普通列
|
||||
var exist = new HashSet<string>(original.Columns.Cast<DataColumn>()
|
||||
.Select(c => c.ColumnName));
|
||||
foreach (var col in normalCols.Where(c => exist.Contains(c.FieldName)
|
||||
&& c.FieldName != keyCol.FieldName))
|
||||
dt.Columns.Add(col.FieldName, original.Columns[col.FieldName].DataType);
|
||||
|
||||
// 求和列
|
||||
foreach (var col in sumColumns.Where(c => exist.Contains(c.FieldName)))
|
||||
if (!dt.Columns.Contains(col.FieldName))
|
||||
dt.Columns.Add(col.FieldName, original.Columns[col.FieldName].DataType);
|
||||
|
||||
// 动态列:统一 string
|
||||
foreach (string h in headers)
|
||||
foreach (var s in subCols)
|
||||
dt.Columns.Add($"{h}_{s.FieldName}", typeof(string));
|
||||
|
||||
/* ============ 2. 分组聚合 ============ */
|
||||
foreach (var grp in original.AsEnumerable().GroupBy(r => r[keyCol.FieldName]))
|
||||
{
|
||||
DataTable dtResult = new DataTable();
|
||||
var newRow = dt.NewRow();
|
||||
var first = grp.First();
|
||||
|
||||
// 添加主键列
|
||||
if (!dtResult.Columns.Contains(GroupPrimary.FieldName))
|
||||
newRow[keyCol.FieldName] = first[keyCol.FieldName];
|
||||
|
||||
// 普通列:取首行
|
||||
foreach (var col in normalCols.Where(c => exist.Contains(c.FieldName)))
|
||||
newRow[col.FieldName] = first[col.FieldName];
|
||||
|
||||
// 求和列
|
||||
foreach (var col in sumColumns.Where(c => exist.Contains(c.FieldName)))
|
||||
{
|
||||
Type dataType = originalDataSource.Columns[GroupPrimary.FieldName].DataType;
|
||||
dtResult.Columns.Add(GroupPrimary.FieldName, dataType);
|
||||
var sum = grp
|
||||
.Where(r => r[col.FieldName] != DBNull.Value)
|
||||
.Sum(r => Convert.ToDecimal(r[col.FieldName]));
|
||||
newRow[col.FieldName] = sum;
|
||||
}
|
||||
|
||||
|
||||
// 添加普通列,仅当原数据源存在时才添加
|
||||
foreach (var col in normalColumns)
|
||||
{
|
||||
if (originalDataSource.Columns.Contains(col.FieldName) && col.FieldName != GroupPrimary.FieldName)
|
||||
// 动态列
|
||||
var lookup = grp.ToLookup(r => r[headerCol.FieldName]?.ToString());
|
||||
foreach (string h in headers)
|
||||
foreach (var s in subCols)
|
||||
{
|
||||
Type dataType = originalDataSource.Columns[col.FieldName].DataType;
|
||||
dtResult.Columns.Add(col.FieldName, dataType);
|
||||
}
|
||||
}
|
||||
|
||||
// 添加动态列 (改为string类型避免异常)
|
||||
foreach (string header in dynamicHeaders)
|
||||
{
|
||||
foreach (var subField in GroupField)
|
||||
{
|
||||
string dynamicFieldName = $"{header}_{subField.FieldName}";
|
||||
if (!dtResult.Columns.Contains(dynamicFieldName))
|
||||
{
|
||||
Type dataType = originalDataSource.Columns[subField.FieldName].DataType;
|
||||
dtResult.Columns.Add(dynamicFieldName, dataType); // <-- 此处已修改为string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 根据主键聚合数据
|
||||
var groupedData = originalDataSource.AsEnumerable()
|
||||
.GroupBy(row => row.Field<string>(GroupPrimary.FieldName));
|
||||
|
||||
foreach (var group in groupedData)
|
||||
{
|
||||
DataRow newRow = dtResult.NewRow();
|
||||
|
||||
// 主键列赋值
|
||||
DataRow firstRow = group.First();
|
||||
newRow[GroupPrimary.FieldName] = firstRow[GroupPrimary.FieldName];
|
||||
|
||||
// 普通列赋值(需判断原数据源中存在)
|
||||
foreach (var col in normalColumns)
|
||||
{
|
||||
if (originalDataSource.Columns.Contains(col.FieldName))
|
||||
newRow[col.FieldName] = firstRow[col.FieldName];
|
||||
string dyn = $"{h}_{s.FieldName}";
|
||||
var hit = lookup[h].FirstOrDefault();
|
||||
newRow[dyn] = hit?[s.FieldName]?.ToString();
|
||||
}
|
||||
|
||||
// 动态聚合列赋值
|
||||
foreach (var header in dynamicHeaders)
|
||||
{
|
||||
var matchedRow = group.FirstOrDefault(r => r.Field<string>(GroupFieldprimary.FieldName) == header);
|
||||
foreach (var subField in GroupField)
|
||||
{
|
||||
string dynamicFieldName = $"{header}_{subField.FieldName}";
|
||||
|
||||
object value = DBNull.Value;
|
||||
|
||||
if (matchedRow != null && originalDataSource.Columns.Contains(subField.FieldName))
|
||||
{
|
||||
value = matchedRow[subField.FieldName];
|
||||
}
|
||||
|
||||
newRow[dynamicFieldName] = value;
|
||||
}
|
||||
}
|
||||
|
||||
dtResult.Rows.Add(newRow);
|
||||
}
|
||||
|
||||
return dtResult;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 最好将异常记录下来
|
||||
Console.WriteLine(ex.Message);
|
||||
return null;
|
||||
dt.Rows.Add(newRow);
|
||||
}
|
||||
|
||||
return dt;
|
||||
}
|
||||
|
||||
|
||||
@@ -8739,4 +8716,30 @@ namespace Lskj.Control
|
||||
{
|
||||
// 只处理列名可解析成日期的列
|
||||
if (!DateTime.TryParse(col.FieldName, out _))
|
||||
|
||||
continue;
|
||||
|
||||
// 取 “Sum” 合计
|
||||
var sumItem = col.Summary
|
||||
.OfType<GridColumnSummaryItem>()
|
||||
.FirstOrDefault(s => s.SummaryType == SummaryItemType.Sum);
|
||||
|
||||
bool needRed = false;
|
||||
|
||||
if (sumItem?.SummaryValue != null &&
|
||||
decimal.TryParse(sumItem.SummaryValue.ToString(), out var colSum) &&
|
||||
jhrowitem.Table.Columns.Contains(col.FieldName) &&
|
||||
decimal.TryParse(jhrowitem[col.FieldName].ToString(), out var planVal))
|
||||
{
|
||||
needRed = (colSum != planVal);
|
||||
}
|
||||
|
||||
// 只改表头文字颜色
|
||||
col.AppearanceHeader.ForeColor = needRed ? Color.Red : Color.Black;
|
||||
col.AppearanceHeader.Options.UseForeColor = true;
|
||||
}
|
||||
// 立刻刷新表头
|
||||
gridView.Invalidate();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user