This code perfectly work on my machine (I have excel 2010) but when my supervisor tried to run but not work on his machine(he have excel 2016) so for excel 2016 do i need to change connection
ConStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileFullPath + ";Extended Properties=\"Excel 12.0;HDR=" + HDR + ";IMEX=0\"";??
string FolderPath = Dts.Variables["User::FolderPath"].Value.ToString();
string TableName = Dts.Variables["User::TableName"].Value.ToString();
string SchemaName = Dts.Variables["User::SchemaName"].Value.ToString();
string SheetNameToLoad = Dts.Variables["User::SheetNameLike"].Value.ToString();
var directory = new DirectoryInfo(FolderPath);
FileInfo[] files = directory.GetFiles();
//Declare and initilize variables
string fileFullPath = "";
SqlConnection myADONETConnection = new SqlConnection();
myADONETConnection = (SqlConnection)(Dts.Connections["DBconnection"].AcquireConnection(Dts.Transaction) as SqlConnection);
////Get one Book(Excel file at a time)
foreach (FileInfo file in files)
{
fileFullPath = FolderPath + "\\" + file.Name;
MessageBox.Show(fileFullPath);
// //Create Excel Connection
string ConStr;
string HDR;
HDR = "YES";
ConStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileFullPath + ";Extended Properties=\"Excel 12.0;HDR=" + HDR + ";IMEX=0\"";
OleDbConnection cnn = new OleDbConnection(ConStr);
// //Get Sheet Name
cnn.Open();
DataTable dtSheet = cnn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
string sheetname;
sheetname = "";
//Only read data from provided SheetNumber
foreach (DataRow drSheet in dtSheet.Rows)
{
sheetname = drSheet["TABLE_NAME"].ToString();
MessageBox.Show(sheetname);
//Load the Data if Sheet Name contains value of SheetNameLike
if (sheetname.Contains(SheetNameToLoad) == true)
{
//Load the DataTable with Sheet Data so we can get the column header
OleDbCommand oconn = new OleDbCommand("select * from [" + sheetname + "] where CityName ='ARLINGTON'", cnn);
OleDbDataAdapter adp = new OleDbDataAdapter(oconn);
DataTable dt = new DataTable();
adp.Fill(dt);
cnn.Close();
//Load Data from DataTable to SQL Server Table.
using (SqlBulkCopy BC = new SqlBulkCopy(myADONETConnection))
{
BC.DestinationTableName = SchemaName + "." + TableName;
BC.WriteToServer(dt);
}
}
}
Did he get the error says ACE provider is not registered? If so, your supervisor need to download and install this on his machine:
https://www.microsoft.com/en-us/download/details.aspx?id=13255
Related
Hi I have a script task which pick up the excel files from a folder. The files have several sheets with names 'Question 1', 'Question 2'....etc.
My problem is that it is not reading or accessing the above sheet with 'space' in between Question and 1...
but when i replace it with (_) i.e. Question_1, Question_2...it is getting retrieved..my script task code is as below..any suggestions what should i change in my code to pick the sheetname as original.
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.IO;
using System.Linq;
using System.Data.OleDb;
using System.Data.SqlClient;
//using System.Text.RegularExpressions;
namespace ST_0762ccf78a5c4709b806530e3c885949
{
[Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
// public static string RemoveSpecialCharacters(string str) { return str.Replace("[^A-Za-z0-9_\\\\.]")};
public void Main()
{
String FolderPath = Dts.Variables["User::FolderPath"].Value.ToString();
string StartingColumn = Dts.Variables["User::StartingColumn"].Value.ToString();
string EndingColumn = Dts.Variables["User::EndingColumn"].Value.ToString();
string StartReadingFromRow = Dts.Variables["User::StartReadingFromRow"].Value.ToString();
var directory = new DirectoryInfo(FolderPath);
FileInfo[] files = directory.GetFiles();
//Declare and initilize variables
string fileFullPath = "";
//Get one Book(Excel file at a time)
foreach (FileInfo file in files)
{
string filename = "";
fileFullPath = FolderPath + "\\" + file.Name;
//filename = file.Name.Replace(".xlsx", "");
filename = file.Name.Replace("'", " ");
MessageBox.Show(fileFullPath);
//Create Excel Connection
string ConStr;
string HDR;
HDR = "YES";
ConStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileFullPath + ";Extended Properties=\"Excel 12.0;HDR=" + HDR + ";IMEX=1\"";
OleDbConnection cnn = new OleDbConnection(ConStr);
//Get the sheetname and filename as columns
/* SqlConnection myADONETConnection = new SqlConnection();
myADONETConnection = (SqlConnection)(Dts.Connections["Pulse_All_Tables"].AcquireConnection(Dts.Transaction) as SqlConnection);
string SQLColumnList = "";
string SQLQueryToGetMatchingColumn = "";
SqlCommand cmd = myADONETConnection.CreateCommand();
cmd.CommandText = SQLQueryToGetMatchingColumn;
SQLColumnList = (string)cmd.ExecuteScalar();*/
//Get Sheet Name
cnn.Open();
DataTable dtSheet = cnn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
string sheetname;
sheetname = "";
//sheetname = sheetname.Replace(" ", string.Empty);
//string sheetname1 = "";
foreach (DataRow drSheet in dtSheet.Rows)
{
//if (drSheet["TABLE_NAME"].ToString().Contains("$"))
if (!drSheet["Table_Name"].ToString().Contains("FilterDatabase") && !drSheet["Table_Name"].ToString().EndsWith("$'"))
{
sheetname = drSheet["TABLE_NAME"].ToString();
//Display Sheet Name , you can comment it out
MessageBox.Show(sheetname);
//Load the DataTable with Sheet Data
//Get the sheetname and filename as columns
//OleDbCommand oconn = new OleDbCommand("select * from [" + sheetname + StartingColumn + StartReadingFromRow + ":" + EndingColumn + "]", cnn);
OleDbCommand oconn = new OleDbCommand("select " + "*" + ",'" + filename + "' AS FileName" + ",'" + sheetname + "' AS SheetName from [" + sheetname + StartingColumn + StartReadingFromRow + ":" + EndingColumn + "]", cnn);
//cnn.Open();
OleDbDataAdapter adp = new OleDbDataAdapter(oconn);
DataTable dt = new DataTable();
adp.Fill(dt);
//drop $from sheet name
sheetname = sheetname.Replace("$", "");
//sheetname = sheetname.Replace((sheetname.Replace("$", "")),"_");
//sheetname1 = sheetname.Replace(" ", "");
// Generate Create Table Script by using Header Column,It will drop the table if Exists and Recreate
string tableDDL = "";
tableDDL += "IF EXISTS (SELECT * FROM sys.objects WHERE object_id = ";
tableDDL += "OBJECT_ID(N'[dbo].[" + filename + "_" + sheetname + "]') AND type in (N'U'))";
tableDDL += "Drop Table [dbo].[" + filename + "_" + sheetname + "]";
tableDDL += "Create table [" + filename + "_" + sheetname + "]";
tableDDL += "(";
for (int i = 0; i < dt.Columns.Count; i++)
{
if (i != dt.Columns.Count - 1)
tableDDL += "[" + dt.Columns[i].ColumnName + "] " + "NVarchar(max)" + ",";
else
tableDDL += "[" + dt.Columns[i].ColumnName + "] " + "NVarchar(max)";
}
tableDDL += ")";
//use ADO.NET connection to Create Table from above Definition
SqlConnection myADONETConnection = new SqlConnection();
myADONETConnection = (SqlConnection)(Dts.Connections["Pulse_All_Tables"].AcquireConnection(Dts.Transaction) as SqlConnection);
//you can comment the messagebox, it is for debugging
MessageBox.Show(tableDDL.ToString());
SqlCommand myCommand = new SqlCommand(tableDDL, myADONETConnection);
myCommand.ExecuteNonQuery();
//Comment this message, it is for debugging
MessageBox.Show("TABLE IS CREATED");
//Load the data from DataTable to SQL Server Table.
SqlBulkCopy blk = new SqlBulkCopy(myADONETConnection);
blk.DestinationTableName = "[" + filename + "_" + sheetname + "]";
blk.WriteToServer(dt);
}
}
}
Dts.TaskResult = (int)ScriptResults.Success;
}
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
}
}
You will have to replace the ' in the Sheetname. Try building your query as in following example:
oconn = new OleDbCommand("SELECT * FROM " + ("[" + dr["TABLE_NAME"].ToString() + "B1:B1]").Replace("'", ""), cnn);
Following a short example app I used to test this logic with a dummy Excel file which featured 3 sheets:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
using System.Data.OleDb;
using System.Data;
using Microsoft.Win32;
namespace ConsoleApp13
{
class Program
{
static void Main(string[] args)
{
string fileName = "c:\\temp\\test.xlsx";
string ConStr = string.Format(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0 Xml;HDR=NO;Empty Text Mode=NullAsEmpty""", fileName);
OleDbConnection cnn = new OleDbConnection(ConStr);
cnn.Open();
DataTable dt = cnn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
foreach (DataRow dr in dt.Rows)
{
Console.WriteLine(dr["TABLE_NAME"]);
//currently hardcoded B1:B1 - has to be replaced with your StartColumn:EndColumn logic
string cmd = "SELECT * FROM " + ("[" + dr["TABLE_NAME"].ToString() + "B1:B1]").Replace("'", "");
Console.WriteLine("\t"+cmd);
DataTable dt2 = new DataTable();
DataSet ds = new DataSet();
OleDbDataAdapter da = new OleDbDataAdapter(cmd, cnn);
da.Fill(ds);
dt2 = ds.Tables[0];
foreach(DataRow dr2 in dt2.Rows)
{
Console.WriteLine("\t" + dr2[0].ToString());
}
}
cnn.Close();
Console.WriteLine("Ende...");
Console.ReadKey();
}
}
}
I am writing a program to read excel using c# and store in a DataTable. When I check the columns in my DataTable while debugging, I see system columns like Table_Schema, Table_Catalog, Table_Name, Table_Type etc. How do I exclude these unwanted columns?
My code:
string sSheetName = null;
string sConnection = null;
int nOutputRow = 0;
DataTable dtTablesList = default(DataTable);
OleDbCommand oleExcelCommand = default(OleDbCommand);
OleDbConnection oleExcelConnection = default(OleDbConnection);
sConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + txtFileName.Text + ";" + "Extended Properties=Excel 8.0;";
oleExcelConnection = new OleDbConnection(sConnection);
oleExcelConnection.Open();
dtTablesList = oleExcelConnection.GetSchema("Tables");
if (dtTablesList.Rows.Count > 0)
{
sSheetName = dtTablesList.Rows[0].Field<string>("TABLE_NAME");
}
dtTablesList.Clear();
dtTablesList.Dispose();
if (!string.IsNullOrEmpty(sSheetName))
{
oleExcelCommand = oleExcelConnection.CreateCommand();
string commandText = "Select * From [" + sSheetName + "]";
oleExcelCommand.CommandType = CommandType.Text;
OleDbDataAdapter daexcel = new OleDbDataAdapter(commandText, oleExcelConnection);
dtTablesList.Locale = System.Globalization.CultureInfo.CurrentCulture;
daexcel.Fill(dtTablesList);
}
oleExcelConnection.Close();
I am trying to copy an excel sheet with 1 Million records into a Data Table. Unfortunately it takes about 47 seconds to complete this process. Is there a better way to copy this information over in less time?
Here's the code that ports the info in:
String constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
fileName +
";Extended Properties='Excel 12.0 XML;';";
OleDbConnection con = new OleDbConnection(constr);
OleDbCommand oconn = new OleDbCommand("Select * From [" + sheetName + "$]", con);
con.Open();
OleDbDataAdapter sda = new OleDbDataAdapter(oconn);
dtTemp.Reset();
dtTemp.TableName = userUpload;
sda.Fill(dtTemp); //Puts imported table into the dtTemp table
con.Close();
string fields = "";
string tempString;
foreach (DataColumn col in dtTemp.Columns) //Generates SQL String from imported table
{
tempString = RemoveSpecialCharacters(col.ColumnName);
if (dtTemp.Columns.IndexOf(col) == dtTemp.Columns.Count - 1)
{
fields += " [" + tempString + "] varchar(255)";
}
else
{
fields += " [" + tempString + "] varchar(255)" + ",";
}
}
fields = fields.Trim();
// createSQLConn(fields, connection, connectionTempDB, dtTemp);
}
here my code which need to save data from excel sheet to database access using C#. I don't get any error but my excel data could not be updated in database access.. What I have to do for this?
My Database Access Tablename is "addsales1".
My Excel sheet name is "addsales1".
string file_name = Application.StartupPath + "\\" + "databaseset.txt";
System.IO.StreamReader objreader;
objreader = new System.IO.StreamReader(file_name);
string sh = objreader.ReadLine();
string con = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + textBox9.Text
+ ";Extended Properties=Excel 8.0;";
OleDbConnection connection = new OleDbConnection(con);
OleDbCommand cmd = new OleDbCommand("INSERT INTO [MS Access;Database=" + sh +
"].[addsales1] SELECT * FROM [addsales1$]");
cmd.Connection = connection;
connection.Open();
cmd.ExecuteNonQuery();
connection.Close();
MessageBox.Show("Sales Details Imported Successfully!");
I read an excel file using OLEDB. Below is the code:
string conn;
conn = ("Provider=Microsoft.ACE.OLEDB.12.0;" +
("Data Source=" + _filename + ";" +
"Extended Properties=\"Excel 12.0;\""));
OleDbConnection oleDBCon = new OleDbConnection(conn);
oleDBCon.Open();
DataTable dt = oleDBCon.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
string SSQL = "SELECT * from [ Sheet1$ ]";
OleDbDataAdapter oleDA = new OleDbDataAdapter(SSQL, conn);
DataSet ds = new DataSet();
oleDA.Fill(ds);
DataTable _DtTable = ds.Tables[0];
oleDBCon.Close();
dataGridView1.DataSource = _DtTable;
foreach (DataRow rows in _DtTable.Rows)
{
string Description = rows[0].ToString();
string Code= rows[1].ToString();
textBox1.AppendText("Printing Description: " + Description + " and Code: " + Code + ",Date:" + DateTime.Now.ToString() + Environment.NewLine);
}
The excel file is as follows:
The data printed in textBox1 are:
Printing Description:Desc 2 and Code: Code 2,Date:20/12/2014 12:36:54 μμ
Printing Description: Desc 3 and Code: Code 3,Date:20/12/2014 12:36:54 μμ
So, my problem is that the 1st row of excel is going to the header of the Datatable. How can I avoid that (without adding any extra 1st row to excel)?
Just add "HDR=No" at the end of your connection string which means "No header row that indicates column but it contains data", then you will be able to fetch 1st row data also.
So your complete connection string would be
conn = ("Provider=Microsoft.ACE.OLEDB.12.0;" +
("Data Source=" + _filename + ";" +
"Extended Properties=\"Excel 12.0;\";HDR=No"));