Это сработало! Спасибо

анные CSV, которые я пытаюсь импортировать в мое приложение VB.NET:

Необработанные данные

Но когда я запускаю его через приложение, оно заполняет только последний ряд:

Выход

Вот код для импорта:

Private Sub btnBrowse_Click(sender As Object, e As EventArgs) Handles btnBrowse.Click
    DataGridView1.ClearSelection()
    ofd.Filter = "(*csv)|*.csv"
    If ComboBox1.Text = "zVBImportTEST" Then
        If (ofd.ShowDialog() = DialogResult.OK) Then
            txtbxFilePath.Text = ofd.FileName
        End If
        Dim colsexpected As Integer = 6
        Dim thereader As New StreamReader(txtbxFilePath.Text, Encoding.ASCII)
        Dim sline As String = ""
        thereader.ReadLine()
        Do
            sline = thereader.ReadLine
            If sline Is Nothing Then Exit Do
            Dim words() As String = sline.Split(",")
            DataGridView1.Rows.Add("")
            For ix As Integer = 0 To 5
                DataGridView1.Rows(DataGridView1.Rows.Count - 1).Cells(ix).Value = words(ix)
            Next

        Loop
        thereader.Close()
    Else
        MessageBox.Show("Please select a project.", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
    End If
End Sub

Я не могу понять, почему другие строки остаются пустыми. Если бы кто-нибудь мог мне помочь, это было бы очень признательно.

Ответы на вопрос(2)

Решение Вопроса

вместо этого используйте класс OleDb при передаче строки подключения для файла CSV.

Вот быстрый пример функции, которая возвращает DataTable на основе содержимого файла CSV:

Private Function ConvertCSVToDataTable(ByVal path As String) As DataTable
    Dim dt As DataTable = New DataTable()
    Using con As OleDb.OleDbConnection = New OleDb.OleDbConnection()
        Try
            con.ConnectionString = String.Format("Provider={0};Data Source={1};Extended Properties=""Text;HDR=YES;FMT=Delimited""", "Microsoft.Jet.OLEDB.4.0", IO.Path.GetDirectoryName(path))
            Using cmd As OleDb.OleDbCommand = New OleDb.OleDbCommand("SELECT * FROM " & IO.Path.GetFileName(path), con)
                Using da As OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter(cmd)
                    con.Open()
                    da.Fill(dt)
                    con.Close()
                End Using
            End Using
        Catch ex As Exception
            Console.WriteLine(ex.ToString())
        Finally
            If con IsNot Nothing AndAlso con.State = ConnectionState.Open Then
                con.Close()
            End If
        End Try
    End Using

    Return dt
End Function

Тогда вот как вы должны связать свой DataGridView:

DataGridView1.DataSource = Me.ConvertCSVToDataTable(ofd.FileName)

Обновить

Поскольку вы хотите указать тип данных DataColumn, объявите DataTable и назначьте его пользовательской функции, но затем перейдите к фактам и измените тип данных определенных столбцов. Вот быстрый (бесплатный и непроверенный) пример:

Dim csv As DataTable = Me.ConvertCSVToDataTable(ofd.FileName)
With csv.Columns
    .Items(0).DataType = GetType(Int32)
    .Items(1).DataType = GetType(Int32)
    .Items(4).DataType = GetType(Int32)
    .Items(5).DataType = GetType(Int32)
End With

DataGridView1.DataSource = csv
 AlanPear15 нояб. 2017 г., 16:29
Мне нравится это решение. Моя единственная проблема заключается в том, что мне нужно указать типы данных для каждого столбца, поэтому я поместил их прямо в таблицу данных, а не в таблицу данных. Конечная цель - вставить данные в сервер SQL. Могу ли я сделать это с данными?
 David15 нояб. 2017 г., 16:12
@ blaze_125 спасибо за это, сегодня я узнал что-то новое.
 AlanPear15 нояб. 2017 г., 18:07
Спасибо, но у меня все еще есть проблема. По какой-то причине все мои строки возвращаются пустыми, но это дает мне правильную сумму. Кроме того, есть ли способ для меня, чтобы включить первую строку в качестве заголовка?
 David15 нояб. 2017 г., 16:45
@AlanPear похоже, что вы знаете тип данных столбца до его загрузки в DataTable. Если это так, то перед привязкой DataGridView установите свойство DataType DataColumns. Для демонстрации я отредактирую пост.

но фрагмент показывает, что вы в данный момент делаете, и как это сделать, чтобы он работал.

using System.Collections.Generic;
using System.Windows.Forms;

namespace DataGridNoBinding_47308996
{
    public partial class Form1 : Form
    {

        DataGridView dgv = new DataGridView();
        public Form1()
        {
            InitializeComponent();
            dgv.Dock = DockStyle.Fill;
            dgv.AutoGenerateColumns = false;
            dgv.Columns.Add("Key","Key");
            dgv.Columns.Add("Value", "Value");
            this.Controls.Add(dgv);

            Dictionary<string, string> dgvdata = new Dictionary<string, string>();
            for (int i = 0; i < 10; i++)
            {
                dgvdata.Add($"key{i}", $"value{i}");
            }

            //AddToGridNoWork(dgvdata);
            AddToGridDoesWork(dgvdata);

        }

        /// <summary>
        /// This method does not work. This emulates what you are currently doing.
        /// </summary>
        /// <param name="dgvdata"></param>
        private void AddToGridNoWork(Dictionary<string, string> dgvdata)
        {
            foreach (KeyValuePair<string, string> item in dgvdata)
            {
                dgv.Rows.Add();
                dgv.Rows[dgv.Rows.Count - 1].Cells[0].Value = item.Key;
                dgv.Rows[dgv.Rows.Count - 1].Cells[1].Value = item.Value;
                dgv.Refresh();
            }
        }


        /// <summary>
        /// This method does work.
        /// Add a new row to the Grid and store the new row index in rowindex
        /// Then use the variable rowindex to update the correct row
        /// </summary>
        /// <param name="dgvdata"></param>
        private void AddToGridDoesWork(Dictionary<string, string> dgvdata)
        {
            foreach (KeyValuePair<string, string> item in dgvdata)
            {
                int rowindex = dgv.Rows.Add();
                dgv.Rows[rowindex].Cells[0].Value = item.Key;
                dgv.Rows[rowindex].Cells[1].Value = item.Value;
            }
        }
    }
}

В вашем приложении VB.net, вероятно, просто нужно что-то вроде этого

dim newRowIndex as Integer
newRowIndex = DataGridView1.Rows.Add("")
For ix As Integer = 0 To 5
    DataGridView1.Rows(newRowIndex).Cells(ix).Value = words(ix)
Next

Вместо DataDriver Вот мой код, повторный запуск с использованием драйвера данных вместо StreamReader

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Data;

namespace DataGridNoBinding_47308996
{
    public partial class Form1 : Form
    {

        DataGridView dgv = new DataGridView();
        public Form1()
        {
            InitializeComponent();
            dgv.Dock = DockStyle.Fill;
            this.Controls.Add(dgv);

            Dictionary<string, string> dgvdata = new Dictionary<string, string>();
            for (int i = 0; i < 10; i++)
            {
                dgvdata.Add($"key{i}", $"value{i}");
            }

            //AddToGridNoWork(dgvdata);
            //AddToGridDoesWork(dgvdata);
            //AddToGridUsingDataDriver(@"M:\StackOverflowQuestionsAndAnswers\DataGridNoBinding_47308996\SampleData.csv");
            AddToGridByBindingTheWholeTable(@"M:\StackOverflowQuestionsAndAnswers\DataGridNoBinding_47308996\SampleData.csv");

        }

        /// <summary>
        /// This method will do what you want using a Data Driver instead of a StreamReader
        /// Though, this method binds the whole DataTable to the DataGridView instead of manually creating 1 row per data row
        /// </summary>
        /// <param name="dataFilePath"></param>
        private void AddToGridByBindingTheWholeTable(string dataFilePath)
        {
            dgv.AutoGenerateColumns = true;

            string connstring = $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={System.IO.Path.GetDirectoryName(dataFilePath)};Extended Properties=\"Text;HDR=NO;FMT=Delimited\"";
            OleDbConnection conn = new OleDbConnection(connstring);
            OleDbCommand command = new OleDbCommand($"select * from {System.IO.Path.GetFileName(dataFilePath)}", conn);
            OleDbDataAdapter dataAdapter = new OleDbDataAdapter(command);
            DataTable dt = new DataTable();
            conn.Open();
            dataAdapter.Fill(dt);
            conn.Close();

            dgv.DataSource = dt;
        }



        /// <summary>
        /// This method will do what you want using a Data Driver instead of a StreamReader
        /// In this method, we are actively creating 1 DataGridRow for each DataRow in the DataTable
        /// </summary>
        /// <param name="dataFilePath"></param>
        private void AddToGridUsingDataDriver(string dataFilePath)
        {
            dgv.AutoGenerateColumns = false;
            dgv.Columns.Add("Key", "Key");
            dgv.Columns.Add("Value", "Value");

            string connstring = $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={System.IO.Path.GetDirectoryName(dataFilePath)};Extended Properties=\"Text;HDR=NO;FMT=Delimited\"";
            OleDbConnection conn = new OleDbConnection(connstring);
            OleDbCommand command = new OleDbCommand($"select * from {System.IO.Path.GetFileName(dataFilePath)}", conn);
            OleDbDataAdapter dataAdapter = new OleDbDataAdapter(command);
            DataTable dt = new DataTable();
            conn.Open();
            dataAdapter.Fill(dt);
            conn.Close();

            if (dt != null && dt.Rows.Count > 0)
            {
                foreach (DataRow item in dt.Rows)
                {
                    int newrowid = dgv.Rows.Add();
                    dgv.Rows[newrowid].Cells[0].Value = item.Field<string>(0);
                    dgv.Rows[newrowid].Cells[1].Value = item.Field<string>(1);
                }
            }
            dgv.Refresh();
        }

        /// <summary>
        /// This method does not work. This emulates what you are currently doing.
        /// </summary>
        /// <param name="dgvdata"></param>
        private void AddToGridNoWork(Dictionary<string, string> dgvdata)
        {
            dgv.AutoGenerateColumns = false;
            dgv.Columns.Add("Key","Key");
            dgv.Columns.Add("Value", "Value");

            foreach (KeyValuePair<string, string> item in dgvdata)
            {
                dgv.Rows.Add();
                dgv.Rows[dgv.Rows.Count - 1].Cells[0].Value = item.Key;
                dgv.Rows[dgv.Rows.Count - 1].Cells[1].Value = item.Value;
                dgv.Refresh();
            }
        }


        /// <summary>
        /// This method does work.
        /// Add a new row to the Grid and store the new row index in rowindex
        /// Then use the variable rowindex to update the correct row
        /// </summary>
        /// <param name="dgvdata"></param>
        private void AddToGridDoesWork(Dictionary<string, string> dgvdata)
        {
            dgv.AutoGenerateColumns = false;
            dgv.Columns.Add("Key", "Key");
            dgv.Columns.Add("Value", "Value");

            foreach (KeyValuePair<string, string> item in dgvdata)
            {
                int rowindex = dgv.Rows.Add();
                dgv.Rows[rowindex].Cells[0].Value = item.Key;
                dgv.Rows[rowindex].Cells[1].Value = item.Value;
            }
        }
    }
}
 AlanPear15 нояб. 2017 г., 15:58
Это сработало! Спасибо

Ваш ответ на вопрос