данные, доступные в vb.net сохраните крайний правый столбец с данными и удалите пустые столбцы

#vb.net #linq #uipath

Вопрос:

У меня есть база данных с приведенными ниже данными, которую я хочу отформатировать, и у меня есть только данные за последние недели.

ID Имя Неделя 1 Неделя 2 Неделя 3 Неделя 4
1 Конор 100 87 3 0
2 Откровенный 35 70 0 0
3 Джефф 35 13 0 57

Я хотел бы сохранить первые 2 столбца, а затем сохранить самый правый столбец, который не равен 0, что дает мне следующее

ID Имя Ценность
1 Конор 3
2 Откровенный 70
3 Джефф 57

Я совсем новичок в LINQ, поэтому немного не уверен, можно ли это сделать или нет, поэтому буду признателен за любую помощь.

Дополнительная информация: Я забыл упомянуть, что создаю решение в UiPath (инструмент RPA), поэтому, хотя код VB был бы лучше для этого экземпляра, предпочтительнее LINQ.

Комментарии:

1. Как DataTable происходит загрузка данных?

2. Я заполняю его из электронной таблицы Excel

Ответ №1:

Linq-это круто, но рабочий код еще круче. Linq не обязательно быстрее. Он выполняет внутренние циклы.

Ваш код в GetDataTable функции будет представлять собой извлечение данных из Excel. Я только что создал таблицу данных, соответствующую вашему примеру.

В событии нажатия кнопки я создал таблицу для хранения результата. Внешний цикл проходит через каждую строку в источнике DataTable . Внутренний For цикл начинается с самого правого столбца dtSource и возвращается к третьему столбцу (индекс 2). Обратите внимание на Step -1 . Это должно работать для любого количества столбцов недели, так как мы используем dtSource.Columns.Count - 1 , как только он находит ненулевое значение, он добавляет запись dtResult и завершает внутренний For переход к следующей строке dtSource .

 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim dtSource = GetDataTable()
    Dim dtResult As New DataTable
    dtResult.Columns.Add("ID", GetType(Integer))
    dtResult.Columns.Add("Name", GetType(String))
    dtResult.Columns.Add("Value", GetType(Integer))
    For Each row As DataRow In dtSource.Rows
        For i = dtSource.Columns.Count - 1 To 2 Step -1
            If CInt(row(i)) <> 0 Then
                dtResult.Rows.Add({row("ID"), row("Name"), row(i)})
                Exit For
            End If
        Next
    Next
    DataGridView1.DataSource = dtResult
End Sub

Private Function GetDataTable() As DataTable
    Dim dt As New DataTable
    dt.Columns.Add("ID", GetType(Integer))
    dt.Columns.Add("Name", GetType(String))
    dt.Columns.Add("Week1", GetType(Integer))
    dt.Columns.Add("Week2", GetType(Integer))
    dt.Columns.Add("Week3", GetType(Integer))
    dt.Columns.Add("Week4", GetType(Integer))
    dt.Rows.Add({1, "Conor", 100, 87, 3, 0})
    dt.Rows.Add({2, "Frank", 35, 70, 0, 0})
    dt.Rows.Add({3, "Jeff", 35, 13, 0, 57})
    Return dt
End Function
 

Комментарии:

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