Итак, у вас есть коллекция документов.Вы хотите отобразить один документ в таблице.Столбцы в таблице представляют Companies
, которые упоминаются в документе.Разные документы могут иметь разное количество компаний.
К счастью, вы хотите, чтобы в вашей таблице отображался только один документ: получив документ, вы знаете, какие компании следует добавить в виде столбцов в таблицу.
Хотя вы определили это водин документ в каждой строке имеет одинаковое количество столбцов , и поэтому в каждом документе используется одинаковое количество компаний, вы не указали, что в каждой строке используются одни и те же компании.
может закончиться так:
Rows[0] has two Cols:
Cols[0] has Company[0]
Cols[1] has Company[1]
Rows[1] has two Cols:
Cols[0] has Company[0]
Cols[1] has Company[2]
Rows[3] has two Cols:
Cols[0] has Company[3]
Cols[1] has Company[4]
Если я посмотрю на ваш код, в этом случае вы захотите показать 5 столбцов.
Row Company[0] Company[1] Company[2] Company[3] Company[4]
----------------------------------------------------------------------------
Row[0] aaa bbb
Row[1] ccc ddd
Row[2] eee fff
Каждый столбец компании в вашей таблице имеет столбецЗаголовок, который показывает название компании.Если у вас есть строка, значения ячеек строки будут либо нулевыми, если компания не используется строкой, либо RebilledAmount
ячейки, в которой используется компания, имя которой указано в заголовке столбца.
Это означает, что как только вы получите свой документ, вам нужно будет знать все используемые компании.Каждая компания становится одной колонной.В каждой колонке вам нужно помнить название компании и идентификационный номер компании
. Для каждой строки, которую вы хотите добавить, вам нужно будет найти столбец, который соответствует идентификаторам компаний.которые используются Cols этой строки.
Мой Visual Basic немного заржавел, поэтому я покажу вам код на C #.Я уверен, что вы сможете понять идею и перевести ее на Visual Basic
Document fetchedDocument = ...
// find out which companies are used by the Document.
// from every company remember the name and the Id:
var companyInfo = fetchedDocument.Rows // take all rows
.SelectMany(row => row.Cols) // from these rows take all Cols
.Select(col => new
{
CompanyId = col.CompanyId, // from every Col take the CompanyId
Name = col.Company.Name, // and the company name
})
.Distinct(); // remove duplicates
Если вы не получили CompanyNames при загрузке документа, вам придется их извлечь вотдельный запрос.Если у вас есть названия компаний где-то локально, в Словаре или что-то еще, найдите их потом:
var companyIds = fetchedDocument.Rows // take all rows
.SelectMany(row => row.Cols) // from all rows take the Cols
.Select(col => col.CompanyId) // from every col take the companyId
.Distinct(); // remove duplicates
// add the CompanyNames
var companyInfo = companyIds.Select(companyId => new
{
Id = companyId,
Name = CompanyCollection[companyId].CompanyName,
});
Как только вы знаете все компании, вы можете добавить все столбцы.Сначала мы добавим столбцы для Description
и RebillAmount
:
myDataGridView.Columns.Clear();
// Column Description:
int columnDescriptionIndex = myDataGridView.Columns.Add(new DataGridViewColumn()
{
Name = "ColDescription", // name of the column
HeaderText = "Description", // header text
ValueType = typeof(string), // this column shows strings
DataPropertyName = "Description", // this column shows property Description
});
// Column RebillAmount:
int columnRebillAmountIndex = myDataGridView.Columns.Add(new DataGridViewColumn()
{
Name = "ColRebillAmount", // name of the column
HeaderText = "RebillAmount", // header text
DataPropertyName = "RebillAmount", // this column shows property RebillAmount
ValueType = typeof(decimal), // this column shows decimals
// if desired: add a DefaultCellStyle to define the display format of the amount
}
Теперь добавим столбцы компании.В каждом столбце компании вы должны помнить идентификатор отображаемой компании.Для этого мы создаем подкласс DataGridViewColumn, который содержит идентификатор отображаемой компании:
class CompanyColumn : DataGridViewColumn
{
public int CompanyId {get; private set;}
public CompanyColumn(int companyId, string companyName)
{
this.CompanyId = companyId;
Name = companyName; // name of the column
HeaderText = companyName; // header text
ValueType = typeof(decimal); // this column shows decimals
// if desired: add a DefaultCellStyle to define the display format
}
}
Добавить один столбец на используемую компанию;для быстрого поиска: поместите индекс столбца в словарь, ключ - companyId, значение columnIndex
var companyColumns = new Dictionary<int, int>()
foreach(var usedCompany in usedCompanies)
{
var columnIndex = myDataGridView.Columns
.Add(new CompanyColumn(usedCompany.Id, usedCompany.Name);
companyColumns.Add(usedCompany.Id, columnIndex);
}
После добавления всех столбцов вы можете добавить строки:
myDataGridView.Rows.Clear();
foreach(var row in document.Rows)
{
var addedRow = myDataGridView.AddRow();
// Description and RebillAmount
addedRow.Cells[colDescriptionIndex].Value = row.Description;
addedRow.Cells[colRebillAmountIndex].Value = row.RebillAmount;
// add the value for every company in the row, in the correct column
foreach (var col in row.Cols
{
// every col has a companyId
// find in the dictionary the index of the column that represents this company
int columnIndex = companyColumns[col.CompanyId];
// put the RebilledAmount in the column with the found index
addedRow.Cells[columnIndex].Value = cell.RebilledAmount;
}
}
Теперь, если ячейка изменяется, вы хотите изменить соответствующее значение в Документах:
void UpdateChangedCell(DataGridViewCell cell)
{
if (cell.ColumnIndex == colDescriptionIndex)
{ // the changed cell is a description cell
string description = (string)cell.Value;
document.Rows[cell.RowIndex].Description = description;
}
else if (cell.ColumnIndex == colRebillAmountIndex)
{ // the changed cell is a rebillAmount cell
decimal rebillAmount = (decimal)cell.Value;
document.Rows[cell.RowIndex].RebillAmount = rebillAmount;
}
else
{ // the changed cell is in one of the company columns:
CompanyColumn column = (CompanyColumn)myDataGridView.Columns[cell.ColumnIndex];
int companyId = column.CompanyId;
decimal rebilledAmount = (decimal)column.Value;
// update the one and only Col in this Row that has CompanyId
var colToUpdate = row.Cols
.Where(col => col.CompanyId == companyId)
.Single();
colToUpdate.RebilledAmount = rebilledAmount;
}
}