Member 12912306 Ответов: 1

Поместите (только) все различные значения из столбца datagridview в массив.


Привет, ребята, спасибо за вашу помощь в Приоре.
Я не программист, я просто пытаюсь решить проблему, которая стоит мне много времени каждый раз, когда мне приходится делать это вручную, так что если это глупо, будьте нежны, пожалуйста.

Вот что я пытаюсь сделать:

У меня есть csv-вывод из базы данных с цифрами продаж, включая все виды транзакций.
Теперь я пытаюсь придумать инструмент littke, который просто суммирует продажи и затраты для каждого клиента и записывает эту информацию обратно в excel.

Я понял, как читать csv-файл, как поместить данные в datatable, а также как показать их через datagridview, сумел отфильтровать

Если бы я знал клиентов в предыдущем файле, это было бы довольно легко, но это отличается для каждого месяца/года), поэтому я пытаюсь найти способ получить всех клиентов в текущем файле, чтобы я мог написать цикл, который суммирует числа для каждого из них.

Что я уже пробовал:

До сих пор у меня есть сами данные в datatable и использовать bindingsource, чтобы показать данные в datagridview.
Я не связываю datagridview напрямую с datatable, потому что мне нужна возможность фильтровать периоды времени, которые я хочу проанализировать.
что мне действительно нравится:
bs.Filter = "[Datum Status] >= #" + anfang.ToString("MM dd yyyy")
    + "# AND [Datum Status] <= #" + ende.ToString("MM dd yyyy") + "#";
//anfang + ende are values I pick from dateTimepickers
dataGridView2.DataSource = bs;

Теперь я хотел бы иметь что-то вроде:
foreach (string s in customerArray)
{
   bs.compute("SUM([Salesvalue])");
   //save it somewhere etc...
   //I know that bindingsources can`t "compute" - just so you get what i try to do
}

Но сначала мне нужно каким-то образом заполнить этот массив значениями для разных клиентов.
у некоторых клиентов есть только одна строка в данных, у других их много.

Я просто не могу получить правильный цикл, поэтому он помещает разных клиентов только один раз в массив.


Мне нужно что-то похожее на это (синтаксис неправильный, я знаю):
 foreach (row in bs)
{
   if (Customervalue is not in customerArray yet)
   { 
       put cellvalue as string in the array
   }
}


Может быть, кто-нибудь из Вас сможет мне помочь?

Большое спасибо и приятного вам Рождества :)

1 Ответов

Рейтинг:
8

Richard Deeming

Это звучит так, как будто вы ищете LINQ[^]:

string[] customers = bs.AsEnumerable()
    .Select(r => r.Field<string>("Customer"))
    .Distinct()
    .ToArray();

var customersWithTotals = bs.AsEnumerable()
    .GroupBy(r => r.Field<string>("Customer"), (customer, rows) => new
    {
        Customer = customer,
        SalesValue = rows.Sum(r => r.Field<decimal>("SalesValue")),
    });

Очевидно, вам нужно будет указать правильные имена столбцов и правильный тип для SalesValue колонка.


Member 12912306

Большое спасибо, это хорошее начало.
Я точно ничего не знаю о LINQ но я посмотрю на это :)

Проблема, которая у меня все еще есть, заключается в том, что мне нужны только суммированные значения отфильтрованного bindingsource. Но Bindingsource не содержит метода AsEnumerable.
Рекомендовали бы вы поместить отфильтрованные значения bindingsource в новую таблицу данных и выполнить вычисление оттуда или есть способ сделать это непосредственно с bindingsource?

Спасибо

Richard Deeming

Извините, я думал, что bs переменная была DataTable.

Вам нужно будет использовать DataTable не BindingSource:

string[] customers = dt.AsEnumerable()
    .Where(r => r.Field<DateTime>("Datum Status") >= anfang && r.Field<DateTime>("Datum Status") <= ende)
    .Select(r => r.Field<string>("Customer"))
    .Distinct()
    .ToArray();

var customersWithTotals = dt.AsEnumerable()
    .Where(r => r.Field<DateTime>("Datum Status") >= anfang && r.Field<DateTime>("Datum Status") <= ende)
    .GroupBy(r => r.Field<string>("Customer"), (customer, rows) => new
    {
        Customer = customer,
        SalesValue = rows.Sum(r => r.Field<decimal>("SalesValue")),
    });