I am working on a windows application in c#.net where I need to import an excel sheet into an Access database by the use of code in c#. I found the following code on the net and tried to use :
string path = #"D:\project_excel";
OleDbConnection con;
System.Data.DataTable dt = null;
//Connection string for oledb
string conn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + path + "; Extended Properties=Excel 8.0;";
con = new OleDbConnection(conn);
try
{
con.Open();
dt = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
String[] excelsheets = new String[dt.Rows.Count];
int i = 0;
foreach (DataRow dr in dt.Rows)
{
excelsheets[i] = dr["TABLE_NAME"].ToString();
i++;
}
// here i manaually give the sheet number in the string array
DataSet ds = new DataSet();
foreach (string temp in excelsheets)
{
// Query to get the data for the excel sheet
//temp is the sheet name
string query = "select * from [" + temp + "]";
OleDbDataAdapter adp = new OleDbDataAdapter(query, con);
adp.Fill(ds, temp);//fill the excel sheet data into a dataset ds
}
}
catch (Exception ex)
{
}
finally
{
con.Close();
}
However it gives an exception which is mentioned below :
The Microsoft Jet database engine cannot open the file 'D:\project_excel'. It is already opened exclusively by another user, or you need permission to view its data.
Further I don't know the meaning of Extended Properties. I am using Microsoft Office 2007 package.If I set Extended Properties = 7.0 it gives following error :
Could not find installable ISAM.
Please help by providing some code sample.
Thanks in advance..
Check to see if the connection string is correct for your Access database version.
For details Visit ConnectionString.com
by
Mohamed Inshafudeen J.
For the error : Could not find installable ISAM.
1: save your excel file as "Excel 97-2003 wrokbook "
2: and also include the reference "Microsoft.Office.Interop.Excel"
best of luck!
Related
My application in WPF allows user to save some data from text boxes into Excel file (using OLEDB connection). I wish to add feature that every time new row is saved into Excel file a sequence number is added into EventID column in that Excel file.
But I'm getting an error while running the application related to parameter #EventId saying: 'parameter has no default value'.
I expect I have written wrong sql1 command to generate the serial number.
I'd appreciate your help.
private void btnSaveNewEvent1_Click_1(object sender, RoutedEventArgs e)
{
object eventName = txtEventName.Text;
object typeValue = txtEventType.Text;
object nameValue = txtAttributeName.Text;
object attribvValue = txtAValue.Text;
object descValue = txtEventDescrip.Text;
System.Data.OleDb.OleDbConnection MyConnection;
System.Data.OleDb.OleDbCommand myCommand = new System.Data.OleDb.OleDbCommand();
System.Data.OleDb.OleDbCommand myCommand1 = new System.Data.OleDb.OleDbCommand();
String sql = null;
String sql1 = null;
MyConnection = new System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source='excel_file\\events2.xlsx'; " +
"Extended Properties=\"Excel 12.0 Xml;HDR=YES;\"");
try
{
//SQL STATEMENT TO SAVE INSERTED BY THE USER VALUES FROM THE TEXT BOXES
//SQL1 STATEMENT TO GENERATE EVENTID NUMBER EACH TIME THE USER SAVES NEW ROW OF DATA
MyConnection.Open();
myCommand.Connection = MyConnection;
sql = "Insert into [events$] (EventID,EventName, Type, Name, [Value], Description) values(#EventID,#EventName,#Type,#Name,#Val,#Desc)";
myCommand.CommandText = sql;
myCommand.Parameters.AddWithValue("#EventID",sql1);
myCommand.Parameters.AddWithValue("#EventName", eventName ?? DBNull.Value);
myCommand.Parameters.AddWithValue("#Type", typeValue ?? DBNull.Value);
myCommand.Parameters.AddWithValue("#Name", nameValue ?? DBNull.Value);
myCommand.Parameters.AddWithValue("#Val", attribvValue ?? DBNull.Value);
myCommand.Parameters.AddWithValue("#Desc", descValue ?? DBNull.Value);
myCommand1.Connection = MyConnection;
sql1= "DECLARE #i int = 0 while #i < EventID BEGIN SET #i = EventID + 1 END";
myCommand1.CommandText = sql1;
myCommand.ExecuteNonQuery();
myCommand1.ExecuteNonQuery();
MyConnection.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
MyConnection.Close();
Events eventsWindow = new Events();
eventsWindow.dgData.Items.Refresh();
}
}
Since your command is running before command1 sql1 = null, That is what your problem is.
You need to set the value of sql1 before executing the command. If you really want the value to be null you need to use DBNull.Value as you have for the other parameters.
Good day to Stackoverflow community,
I am in need of some expert assistance. I have an MVC4 web app that has a few rich text box fields powered by TinyMCE. Up until now the system is working great. Last week my client informed me that they want to export the data stored in Microsoft SQL to Excel to run custom reports.
I am able to export the data to excel with the code supplied. However it is exporting the data in RTF rather than Plain text. This is causing issues when they try to read the content.
Due to lack of knowledge and or understanding I am unable to figure this out. I did read that it is possible to use regex to do this however I have no idea how to implement this. So I turn to you for assistance.
public ActionResult ExportReferralData()
{
GridView gv = new GridView();
gv.DataSource = db.Referrals.ToList();
gv.DataBind();
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment; filename=UnderwritingReferrals.xls");
Response.ContentType = "application/ms-excel";
Response.AddHeader("Content-Type", "application/vnd.ms-excel");
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
gv.RenderControl(htw);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
return RedirectToAction("Index");
}
I would really appreciate any assistance. and thank you in advance.
I have looked for solutions on YouTube and web forums with out any success.
Kind Regards
Francois Muller
One option you can perform is to massage the Data you write to the XML file.
For example, idenfity in your string and replace it with string.Empty.
Similarly can be replaced with string.Empty.
Once you have identified all the variants of the Rich Text HTML tags, you can just create a list of the Tags, and inside a for FOR loop replace each of them with a suitable string.
Did you try saving the file as .xslx and sending over to the client.
The newer Excel format might handle the data more gracefully?
Add this function to your code, and then you can invoke the function passing it in the HTML string. The return output will be HTML free.
Warning: This does not work for all cases and should not be used to process untrusted user input. Please test it with variants of your input string.
public static string StripTagsCharArray(string source)
{
char[] array = new char[source.Length];
int arrayIndex = 0;
bool inside = false;
for (int i = 0; i < source.Length; i++)
{
char let = source[i];
if (let == '<')
{ inside = true; continue; }
if (let == '>') { inside = false; continue; }
if (!inside) { array[arrayIndex] = let; arrayIndex++; }
}
return new string(array, 0, arrayIndex);
}
So I managed to resolve this issue by changing the original code as follow:
As I'm only trying to convert a few columns, I found this to be working well. This will ensure each records is separated by row in Excel and converts the Html to plain text allowing users to add column filters in Excel.
I hope this helps any one else that has a similar issue.
GridView gv = new GridView();
var From = RExportFrom;
var To = RExportTo;
if (RExportFrom == null || RExportTo == null)
{
/* The actual code to be used */
gv.DataSource = db.Referrals.OrderBy(m =>m.Date_Logged).ToList();
}
else
{
gv.DataSource = db.Referrals.Where(m => m.Date_Logged >= From && m.Date_Logged <= To).OrderBy(m => m.Date_Logged).ToList();
}
gv.DataBind();
foreach (GridViewRow row in gv.Rows)
{
if (row.Cells[20].Text.Contains("<"))
{
row.Cells[20].Text = Regex.Replace(row.Cells[20].Text, "<(?<tag>.+?)(>|>)", " ");
}
if (row.Cells[21].Text.Contains("<"))
{
row.Cells[21].Text = Regex.Replace(row.Cells[21].Text, "<(?<tag>.+?)(>|>)", " ");
}
if (row.Cells[22].Text.Contains("<"))
{
row.Cells[22].Text = Regex.Replace(row.Cells[22].Text, "<(?<tag>.+?)(>|>)", " ");
}
if (row.Cells[37].Text.Contains("<"))
{
row.Cells[37].Text = Regex.Replace(row.Cells[37].Text, "<(?<tag>.+?)(>|>)", " ");
}
if (row.Cells[50].Text.Contains("<"))
{
row.Cells[50].Text = Regex.Replace(row.Cells[37].Text, "<(?<tag>.+?)(>|>)", " ");
}
}
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment; filename=Referrals " + DateTime.Now.ToString("dd/MM/yyyy") + ".xls");
Response.ContentType = "application/ms-excel";
Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.AddHeader("Content-Type", "application/vnd.ms-excel");
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
gv.RenderControl(htw);
//This code will export the data to Excel and remove all HTML Tags to pass everything into Plain text.
//I am using HttpUtility.HtmlDecode twice as the first instance changes null values to "Â" the second time it will run the replace code.
//I am using Regex.Replace to change the headings to more understandable headings rather than the headings produced by the Model.
Response.Write(HttpUtility.HtmlDecode(sw.ToString())
.Replace("Cover_Details", "Referral Detail")
.Replace("Id", "Identity Number")
.Replace("Unique_Ref", "Reference Number")
.Replace("Date_Logged", "Date Logged")
.Replace("Logged_By", "File Number")
.Replace("Date_Referral", "Date of Referral")
.Replace("Referred_By", "Name of Referrer")
.Replace("UWRules", "Underwriting Rules")
.Replace("Referred_To", "Name of Referrer")
);
Response.Flush();
Response.End();
TempData["success"] = "Data successfully exported!";
return RedirectToAction("Index");
}
I created a simple console application to test the ability to push data from an excel file into a dataset and it works fine on my local machine (win 8.1). However, when I move the project to server 2012, and run it, it always returns an empty dataset. I'm a little suspicious their is a local policy the account needs, however the account is a local admin.
class Class1
{
public DataSet ReturnExcelDataTable(string fileName)
{
DataSet dsImport = new DataSet();
DataSet ds = new DataSet();
string strConn;
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source=" + fileName +
";Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1\";";
try
{
OleDbDataAdapter cmd = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", strConn);
cmd.Fill(dsImport);
}
catch (Exception ex)
{
}
return dsImport;
}
}
static void Main(string[] args)
{
Class1 xls = new Class1();
string fileName = #"c:\temp\targets\test3.xlsx";
DataSet dt = xls.ReturnExcelDataTable(fileName);
foreach (DataRow dr in dt.Tables[0].Rows)
{
Console.WriteLine(dr[0]);
Console.ReadKey();
}
}
string connectionString = ConfigurationManager.ConnectionStrings["myConnection"].ConnectionString;
const string query = "my Select query here";
List<long> myList = new List<long>();
using (SqlConnection con = new SqlConnection(connectionString))
{
con.Open();
using (SqlCommand selectCommand = new SqlCommand(query, con))
{
selectCommand.CommandType = CommandType.Text;
SqlDataReader sqlreader = selectCommand.ExecuteReader();
while (sqlreader.Read())
{
long Id = (long)sqlreader["Id"];
List.Add(Convert.ToInt32(sqlreader[0].ToString()));
using (SqlCommand insertCommand = new SqlCommand("dbo.SP_Data", con))
{
insertCommand.CommandType = CommandType.StoredProcedure;
insertCommand.Parameters.Add("#Id", SqlDbType.BigInt).Value = Id;
insertCommand.Parameters.Add("#StatusId", SqlDbType.BigInt).Value = 1;
insertCommand.Parameters.Add("#ReportDate", SqlDbType.DateTime).Value = DateTime.Now;
insertCommand.Parameters.Add("#CreatedDate", SqlDbType.DateTime).Value = DateTime.Now;
insertCommand.Parameters.Add("#CreatedBy", SqlDbType.UniqueIdentifier).Value = DefaultUser();
insertCommand.ExecuteNonQuery();
}
}
}
}
I am getting the error "There is already an open DataReader associated with this Command which must be closed first." at the last line [insertCommand.ExecuteNonQuery();
You need to enalbe MARS in your connection string (MARS = Multiple Active Result Sets)
In short, this particular flag, when enabled in the connection string, allows to use the same connection used by the SqlDataReader also for executing commands. Otherwise, as stated by MSDN the connection is busy serving the SqlDataReader and cannot execute other commands.
Before Sql Server 2005 the developpers were forced to create, open and use another connection. (Still possible if your environment doesn't allow to change the connection string)
More info about MARS could be found on this MSDN article
Examples of connection string that uses MARS
Porting MSSQL Application to Sybase (ASE 15.0), and experiencing a problem when I call GetDeleteCommand.
The error reported is:
Dynamic SQL generation for the DeleteCommand is not supported against
a SelectCommand that does not return any key column information.
The problem only occurs for temporary table, identical non-temporary table works fine.
Table contains a primary key.
Reproduced using test program below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
using System.Data;
namespace DataAdapterTempTable
{
class Program
{
static void Main(string[] args)
{
String ConnectionString = "Provider=ASEOLEDB;Data Source=devsun3:5003;Initial Catalog=ctc;User ID=aigtac12;Password=aigtac12;"; // sybase connection string
//String ConnectionString = "Provider=SQLOLEDB;Data Source=fiji;Persist Security Info=False;Initial Catalog=nxgn0811;Integrated Security=SSPI"; // mssql connection string
String TableName = "#alex_temporary_table_test"; // does not work for sybase
//String TableName = "alex_real_table_test"; // works for sybase + mssql
String CreateStatement = "create table " + TableName + " (currency_id varchar(4) primary key, rate decimal(25,6), format char(1))";
String SelectStatement = "select * from " + TableName;
try
{
OleDbConnection con = null;
con = new OleDbConnection(ConnectionString);
con.Open();
OleDbCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = CreateStatement;
int count = cmd.ExecuteNonQuery();
OleDbCommand cm1 = con.CreateCommand();
cm1.CommandType = CommandType.Text;
cm1.CommandText = SelectStatement;
OleDbDataAdapter DA2 = new OleDbDataAdapter(cm1);
DataTable DT2 = new DataTable();
DA2.FillSchema(DT2, SchemaType.Mapped);
OleDbCommandBuilder cmdbldr = new OleDbCommandBuilder(DA2);
DA2.InsertCommand = cmdbldr.GetInsertCommand();
DA2.DeleteCommand = cmdbldr.GetDeleteCommand(); // this line fails in sybase for temporary table
DA2.UpdateCommand = cmdbldr.GetUpdateCommand();
DA2.Fill(DT2);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
}
In the select statement, instead of * use the column names.
Contacted Sybase support, turns out I had to update some system stored procedures. There is a folder that ends with "oledb\sp", and I had to run a .bat file from the folder. I got the latest ebf and ran the batch file install_oledb_sprocs.bat, the problem went away. Worth mentioning, that sybase 15.5 did not have the issue without patching.
P.S. Thank you to 'aF' for your time looking into the issue.