 |
|
 |
I used this in a VB project and I added a snipit for dynamic Columns.
Private Sub btnLoadData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoadData.Click
Try
If String.IsNullOrEmpty(txtFilePath.Text.Trim()) Then
MessageBox.Show("Please supply file name")
Return
End If
Dim rdr As New System.IO.StreamReader(txtFilePath.Text.Trim())
Dim inputLine As String = ""
Dim dt As New DataTable()
inputLine = rdr.ReadLine()
Dim Myarr As String()
Myarr = inputLine.Split(","c)
For Each ar_loopVariable As String In Myarr
dt.Columns.Add(ar_loopVariable)
Next
Dim row As DataRow
While (InlineAssignHelper(inputLine, rdr.ReadLine())) IsNot Nothing
Dim arr As String()
arr = inputLine.Split(","c)
row = dt.NewRow()
Dim X As Integer = 0
For Each ar_loopVariable As String In Myarr
row(ar_loopVariable) = arr(X)
X += 1
Next
dt.Rows.Add(row)
End While
dataGridView1.DataSource = dt
rdr.Close()
Catch generatedExceptionName As Exception
Throw
End Try
End Sub
|
|
|
|
 |
|
 |
Never used C# before & trying to load data from datagrid to sql database, but getting errors on compile in ColumnMappings in Save to database. The datagrid functions fine. Code is:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class frmImport : Form
{
System.Data.SqlClient.SqlConnection con;
public frmImport()
{
InitializeComponent();
}
private string fileCSV; //full file name
private void Form1_Load(object sender, EventArgs e)
{
try
{
con = new System.Data.SqlClient.SqlConnection();
con.ConnectionString = "Data Source=.\\SQLEXPRESS;" +
"AttachDbFilename=C:\\SAP_test.mdf;" +
"Trusted_Connection=yes;" +
"Integrated Security=True;Connect Timeout=30;User Instance=True";
con.Open();
//MessageBox.Show("Database Open");
//con.Close();
//MessageBox.Show("Database Closed");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void mnuQuit_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Are you sure you want to exit?", "Exit", MessageBoxButtons.OKCancel) == DialogResult.OK)
{
Application.Exit();
}
}
private void mnuOpen_Click(object sender, EventArgs e)
{
string Chosen_File = "";
openFD.InitialDirectory = "C:";
openFD.Title = "Select csv file";
openFD.Filter = "CSV|*.csv|TEXT|*.txt";
openFD.FileName = "";
if (openFD.ShowDialog() == DialogResult.OK)
{
this.txtFileName.Text = openFD.FileName.ToString();
}
else
{
Chosen_File = openFD.FileName;
}
}
private void txtFileName_TextChanged(object sender, EventArgs e)
{
this.fileCSV = this.txtFileName.Text;
}
private void btnBrowse_Click(object sender, EventArgs e)
{
string Chosen_File = "";
openFD.InitialDirectory = "C:";
openFD.Title = "Select csv file";
openFD.Filter = "CSV|*.csv|TEXT|*.txt";
openFD.FileName = "";
if (openFD.ShowDialog() == DialogResult.OK)
{
this.txtFileName.Text = openFD.FileName.ToString();
}
else
{
Chosen_File = openFD.FileName;
}
}
private void btnLoad_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrEmpty(txtFileName.Text.Trim()))
//Check if Table name was provided
{
MessageBox.Show("Please supply File Name");
return;
}
System.IO.StreamReader rdr =
new System.IO.StreamReader(this.fileCSV = this.txtFileName.Text);
//Stream reader reads a file. File path
//and name are supplied from where to read the file.
string inputLine = "";
DataTable dt = new DataTable();
//A data table is similar to a Database table.
//Define the columns.
dt.Columns.Add("plant");
dt.Columns.Add("emp_no");
dt.Columns.Add("ssn");
dt.Columns.Add("base_rate");
dt.Columns.Add("misc_pay");
dt.Columns.Add("shift");
dt.Columns.Add("spec_pay");
dt.Columns.Add("reg_hours");
dt.Columns.Add("overtime");
dt.Columns.Add("bonus_percent");
dt.Columns.Add("bonus_hours");
dt.Columns.Add("pay_end_dt");
DataRow row; //Declare a row, which will be added to the above data table
while ((inputLine = rdr.ReadLine()) != null)
//Read while the line is not null
{
string[] arr;
arr = inputLine.Split(',');
//splitting the line which was read by the stream reader object
row = dt.NewRow();
row["plant"] = arr[0];
row["emp_no"] = arr[1];
row["ssn"] = arr[2];
row["base_rate"] = arr[3];
row["misc_pay"] = arr[4];
row["shift"] = arr[5];
row["spec_pay"] = arr[6];
row["reg_hours"] = arr[7];
row["overtime"] = arr[8];
row["bonus_percent"] = arr[9];
row["bonus_hours"] = arr[10];
row["pay_end_dt"] = arr[11];
dt.Rows.Add(row);
}
dt.Rows.RemoveAt(0); //Remove the first column since its
//the column name not necessary to insert in the database table
dataGridView1.DataSource = dt; //setting the data source to the gridview
rdr.Close(); //release the stream reader
}
catch (Exception)
{
throw;
}
}
private void btnImport_Click(object sender, EventArgs e)
{
string filepath = "C:\\test_eupay3dl.csv";
//string filepath = this.txtFileName.Text;
this.txtFileName.Text = openFD.FileName.ToString();
StreamReader sr = new StreamReader(filepath);
string line = sr.ReadLine();
string[] value = line.Split(',');
DataTable dt = new DataTable();
DataRow row;
//foreach (string dc in value)
//{
// dt.Columns.Add(new DataColumn(dc));
//}
while (!sr.EndOfStream)
{
value = sr.ReadLine().Split(',');
if (value.Length == dt.Columns.Count)
{
row = dt.NewRow();
row.ItemArray = value;
dt.Rows.Add(row);
}
}
SqlBulkCopy bc = new SqlBulkCopy(con.ConnectionString, SqlBulkCopyOptions.TableLock);
bc.DestinationTableName = "pay3dl_out";
bc.BatchSize = dt.Rows.Count;
try
{
bc.DestinationTableName = "pay3dl_out";
//You need to define the target table name where
//the data will be copied
//Since the requirement is not to read data directly from the file
//I have included a gridview, where the
//raw data will be shown to the user.
//So that the user can change the data if he wants
for (int i = 0; i < dataGridView1.ColumnCount; i++)
//reading the column names
{
bc.ColumnMappings.Add(
dataGridView1.Columns[i].Name = "plant";
dataGridView1.Columns[i].Name= "emp_no";
dataGridView1.Columns[i].Name= "ssn";
dataGridView1.Columns[i].Name= "base_rate";
dataGridView1.Columns[i].Name= "misc_pay";
dataGridView1.Columns[i].Name= "shift";
dataGridView1.Columns[i].Name= "spec_pay";
dataGridView1.Columns[i].Name= "reg_hours";
dataGridView1.Columns[i].Name= "overtime";
dataGridView1.Columns[i].Name= "bonus_percent";
dataGridView1.Columns[i].Name= "bonus_hours";
dataGridView1.Columns[i].Name= "pay_end_dt";
//Column mapping , supplying source column
//and destination column
}
//DataTable dt = new DataTable();
dt = (DataTable)dataGridView1.DataSource;
//Storing the data in a data table, though you can do it by
//directly passing Grid View Data Source to the following function
bc.WriteToServer(dt);
bc.Close();//Release the resources
MessageBox.Show("Saved Successfully");
}
catch (Exception exp)
{
MessageBox.Show(exp.Message); //Catch any exception if occurs
}
}
}
}
|
|
|
|
 |
|
 |
Hi , thanks for your mail. Can you please post , what the error message says.
|
|
|
|
 |
|
 |
Ok, I understood, please replace your column mapping code with the following code.
I think the problem is u are not supplying destination column name.
Please try this.
SqlBulkCopy bc = new SqlBulkCopy(con.ConnectionString, SqlBulkCopyOptions.TableLock);
bc.DestinationTableName = "pay3dl_out";
bc.BatchSize = dt.Rows.Count;
for (int i = 0; i < dataGridView1.ColumnCount; i++)
//reading the column names
{
SqlBulkCopyColumnMapping mapping = new SqlBulkCopyColumnMapping();
mapping.SourceColumn = dataGridView1.Columns[i].Name;
mapping.DestinationColumn = "Destination Column Name"; //It could be same name as dataGridView1.Columns[i].Name;
bc.ColumnMappings.Add(mapping);
}
//Good luck. And let me know if you need more help.
//Regards
Angsuman
|
|
|
|
 |
|
 |
I've added the following code:
SqlBulkCopyColumnMapping mapping = new SqlBulkCopyColumnMapping();
mapping.SourceColumn = dataGridView1.Columns[i].Name;
mapping.DestinationColumn = "plant"; //It could be same name as dataGridView1.Columns[i].Name;
mapping.DestinationColumn = "emp_no";
mapping.DestinationColumn = "ssn";
mapping.DestinationColumn = "base_rate";
mapping.DestinationColumn = "misc_pay";
mapping.DestinationColumn = "shift";
mapping.DestinationColumn = "spec_pay";
mapping.DestinationColumn = "reg_hours";
mapping.DestinationColumn = "overtime";
mapping.DestinationColumn = "bonus_percent";
mapping.DestinationColumn = "bonus_hours";
mapping.DestinationColumn = "pay_end_dt";
bc.ColumnMappings.Add(mapping);
Now, getting error message "The given ColumnMapping does not match up with any column in the source or destination". I hope I followed your instructions correctly. As I mentioned, please forgive me as I've never coded in C# before and really struggling to understand.
So, many Thanks to you and best regards for all your help.
|
|
|
|
 |
|
 |
hi there, thanks for your mail.
the mistake is you are not passing 2 arguments in the column mapping function.
please follow this code.
SqlBulkCopyColumnMapping mapping = new SqlBulkCopyColumnMapping();
mapping.SourceColumn = dataGridView1.Columns[i].Name;
mapping.DestinationColumn = "plant";
bc.ColumnMappings.Add(mapping);
mapping = new SqlBulkCopyColumnMapping();
mapping.SourceColumn = dataGridView1.Columns[i].Name;//please supply proper column name
mapping.DestinationColumn = "plant"; //It could be same name as dataGridView1.Columns[i].Name;
bc.ColumnMappings.Add(mapping);
mapping = new SqlBulkCopyColumnMapping();
mapping.SourceColumn = dataGridView1.Columns[i].Name;//please supply proper column name
mapping.DestinationColumn = "emp_no";
bc.ColumnMappings.Add(mapping);
mapping = new SqlBulkCopyColumnMapping();
mapping.SourceColumn = dataGridView1.Columns[i].Name;//please supply proper column name
mapping.DestinationColumn = "ssn";
bc.ColumnMappings.Add(mapping);
mapping = new SqlBulkCopyColumnMapping();
mapping.SourceColumn = dataGridView1.Columns[i].Name;//please supply proper column name
mapping.DestinationColumn = "base_rate";
bc.ColumnMappings.Add(mapping);
mapping = new SqlBulkCopyColumnMapping();
mapping.SourceColumn = dataGridView1.Columns[i].Name;//please supply proper column name
mapping.DestinationColumn = "misc_pay";
bc.ColumnMappings.Add(mapping);
mapping = new SqlBulkCopyColumnMapping();
mapping.SourceColumn = dataGridView1.Columns[i].Name;//please supply proper column name
mapping.DestinationColumn = "shift";
bc.ColumnMappings.Add(mapping);
mapping = new SqlBulkCopyColumnMapping();
mapping.SourceColumn = dataGridView1.Columns[i].Name;//please supply proper column name
mapping.DestinationColumn = "spec_pay";
bc.ColumnMappings.Add(mapping);
mapping = new SqlBulkCopyColumnMapping();
mapping.SourceColumn = dataGridView1.Columns[i].Name;//please supply proper column name
mapping.DestinationColumn = "reg_hours";
bc.ColumnMappings.Add(mapping);
mapping = new SqlBulkCopyColumnMapping();
mapping.SourceColumn = dataGridView1.Columns[i].Name;//please supply proper column name
mapping.DestinationColumn = "overtime";
bc.ColumnMappings.Add(mapping);
mapping = new SqlBulkCopyColumnMapping();
mapping.SourceColumn = dataGridView1.Columns[i].Name;//please supply proper column name
mapping.DestinationColumn = "bonus_percent";
bc.ColumnMappings.Add(mapping);
mapping = new SqlBulkCopyColumnMapping();
mapping.SourceColumn = dataGridView1.Columns[i].Name;//please supply proper column name
mapping.DestinationColumn = "bonus_hours";
bc.ColumnMappings.Add(mapping);
mapping = new SqlBulkCopyColumnMapping();
mapping.SourceColumn = dataGridView1.Columns[i].Name;//please supply proper column name
mapping.DestinationColumn = "pay_end_dt";
bc.ColumnMappings.Add(mapping);
Please write back if you need more help
Thanks
Angsuman
|
|
|
|
 |
|
 |
Thank You for responding. I'm still getting the same error and don't understand what I'm doing wrong. My csv file does not contain a header row, only data. My sqlexpress table column names are the same names as what I'm using to load the datagrid and what is specified on the mapping.DestinationColumn statement. The datagrid loads fine. I'll use the "plant" as example.
mapping = new SqlBulkCopyColumnMapping();
mapping.SourceColumn = dataGridView1.Columns[i].Name;//please supply proper column name
mapping.DestinationColumn = "plant"; //It could be same name as dataGridView1.Columns[i].Name;
bc.ColumnMappings.Add(mapping);
If I change the "Name" on line 2 to "plant" then I get the error "Error 1 Only assignment, call, increment, decrement, and new object expressions can be used as a statement".
If I leave off the quotes off on plant then I get the error "Error 1 System.Windows.Forms.DataGridViewColumn' does not contain a definition for 'plant' and no extension method 'plant' accepting a first argument of type 'System.Windows.Forms.DataGridViewColumn' could be found (are you missing a using directive or an assembly reference?)
If I leave it set to Name then when I run the program and attempt to load to sql I get a dialogue box that says "The given Columnmapping does not match up with any column in the source or destination".
I apologize for bothering you on this, but I very much appreciate your help. You can email me directly if you wish kparker@americanbuildings.com
Many Thanks..
|
|
|
|
 |
|
 |
I couldn't find the solution anywhere
|
|
|
|
 |
|
 |
good for beginners, but would be nice to see more detail, regarding the column mapping. perhaps adding to this
developing a front end wizard style csv importer. whereby the user can specify which csv fields they want to import to which database field and add in some validation so that the data types and constraints are checked
|
|
|
|
 |
|
 |
Hi Angsuman, you dont have this example in VB by any chance?
Cheers
|
|
|
|
 |
|
 |
Hi, thanks for your message. Do you need this in vb? If yes, then you can find a lot of code converter in the net.
Please try one.
|
|
|
|
 |
|
 |
Thanks I'll post my vb source once I have it going
|
|
|
|
 |
|
 |
Heres the VB (and it worked )
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.Windows.Forms
Imports System.Data.SqlClient
Class Form1
Private Sub btnSaveFile_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSaveFile.Click
Try
If String.IsNullOrEmpty(txtServerConfiguration.Text.Trim()) Then
MessageBox.Show("Please supply Server Configuration")
Exit Sub
End If
If String.IsNullOrEmpty(txtTableName.Text.Trim()) Then
MessageBox.Show("Please supply Table Name")
Exit Sub
End If
Dim sqlbulkCopy As New SqlBulkCopy(txtServerConfiguration.Text.Trim())
sqlbulkCopy.DestinationTableName = txtTableName.Text.Trim()
For i As Integer = 0 To dataGridView1.ColumnCount - 1
sqlbulkCopy.ColumnMappings.Add(dataGridView1.Columns(i).Name, dataGridView1.Columns(i).Name)
Next
Dim dt As New DataTable()
dt = DirectCast(dataGridView1.DataSource, DataTable)
sqlbulkCopy.WriteToServer(dt)
sqlbulkCopy.Close()
MessageBox.Show("Saved Successfully")
Catch exp As Exception
MessageBox.Show(exp.Message)
End Try
End Sub
Private Sub btnLoadFile_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoadFile.Click
Try
Dim dResult As New DialogResult()
dResult = OpenFileDialog1.ShowDialog()
If dResult = DialogResult.OK Then
txtFilePath.Text = OpenFileDialog1.FileName
Else
Exit Sub
End If
Catch exp As Exception
MessageBox.Show(exp.Message)
End Try
End Sub
Private Sub btnLoadData_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoadData.Click
Try
If String.IsNullOrEmpty(txtFilePath.Text.Trim()) Then
MessageBox.Show("Please supply file name")
Exit Sub
End If
Dim rdr As New System.IO.StreamReader(txtFilePath.Text.Trim())
Dim inputLine As String = ""
Dim dt As New DataTable()
dt.Columns.Add("CompanyName")
dt.Columns.Add("Volume")
Dim row As DataRow
While (InlineAssignHelper(inputLine, rdr.ReadLine())) IsNot Nothing
Dim arr As String()
arr = inputLine.Split(","c)
row = dt.NewRow()
row("Companyname") = arr(0)
row("Volume") = arr(1)
dt.Rows.Add(row)
End While
dt.Rows.RemoveAt(0)
dataGridView1.DataSource = dt
rdr.Close()
Catch generatedExceptionName As Exception
Throw
End Try
End Sub
Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T
target = value
Return value
End Function
End Class
Thanks again for the great article!!!!!
|
|
|
|
 |
|
|
 |
|
 |
Hello!
This VB Code is awesome... could I make it work as a form called from INSIDE a project?
For example, I am creating a simple guests application, which records First Names, Last Names, SSN, Member Number, and a bit whether they are attending the meeting or not. The CSV file has monthly about 150 new users, that need to be appended to the database.
I really don't need to write down a connection configuration, because I will be importing from inside the same application...
I can see the data inside the Grid, and I formatted the code to the point where all the data would to to their specific columns. I just need to know how to save the data in the Data Grid to the server, without having to specify a connection, because it is already made automatically by the application on startup.
Worth Mentioning:
This is a VB2008 Express application.
I am a newbie, so I am kind of stuck. Any help will be appreciated.
Thanks!
|
|
|
|
 |
|
 |
Hi there, thanks for your inquiry.
Please take a look at the follwing code.
SqlBulkCopy sqlbulkCopy = new SqlBulkCopy(txtServerConfiguration.Text.Trim());
sqlbulkCopy.DestinationTableName = txtTableName.Text.Trim();
From your mail what i understand is that:
1)You need some way to to supply the connection string to sqlbulkcopy, instead of writing something as above.
As you have said your connection is automatically supplied during application startup. So it means, it exists some where in your
application. Please find a way to get that settings. Such as:
1) If it is stored in app.config file. You can use "ConfigurationManager.ConnectionString" - the built in functions to read the connection from that file.
2) If it is stored in web.config file. still You can use "WebConfigurationManager.ConnectionString" - the built in functions to read the connection from that file.
And then lasty supply this connection string in the parameter instead of "txtServerConfiguration.Text.Trim();"
Thats it. happy coding. Please let me know if you need more help.
chakraborty
|
|
|
|
 |
|
 |
The article was really helpful but i could not save the data from the unbound datagridview into the table
|
|
|
|
 |
|
 |
Hi could you be a little more detailed because I encounter error
while trying to execute the first function.
|
|
|
|
 |
|
 |
hi , thanks for message. What the error says.
|
|
|
|
 |
|
 |
It was really a needful article.
|
|
|
|
 |
|
 |
I hope there are no embedded commas or quotes in the data.
This block of code doesn't hardcode a provider, works on 64bit servers and supports commas and quotes in the data.
It doesn't support reording the columns, but that should be easy
public void DoImport(string providerName, string connectionString, string tableName, string fileName)
{
const RegexOptions options = ((RegexOptions.IgnorePatternWhitespace |RegexOptions.Multiline) |RegexOptions.IgnoreCase);
Regex regex = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))", options);
var factory = DbProviderFactories.GetFactory(providerName);
var commandBuilder = factory.CreateCommandBuilder();
var connectionStringBuilder = factory.CreateConnectionStringBuilder()
?? new DbConnectionStringBuilder();
connectionStringBuilder.ConnectionString = connectionString;
var conn = factory.CreateConnection();
conn.ConnectionString = connectionStringBuilder.ConnectionString;
using (var cmd = conn.CreateCommand())
using (var da = factory.CreateDataAdapter())
using (var dt = new DataTable())
{
cmd.CommandText = string.Format("select * from {0}", tableName);
da.SelectCommand = cmd;
commandBuilder.DataAdapter = da;
da.FillSchema(dt, SchemaType.Source);
dt.BeginLoadData();
using (var filestream = System.IO.File.OpenText(fileName))
{
for (int i = 0; i < _skipRows; i++)
{
filestream.ReadLine();
if (filestream.EndOfStream)
{
break;
}
}
while (!filestream.EndOfStream)
{
string line = filestream.ReadLine();
var oo = regex.Split(line);
}
}
dt.EndLoadData();
}
}
modified on Thursday, February 11, 2010 10:21 PM
|
|
|
|
 |