Transfer Excel data into a SQL Server table using file upload - asp.net

I need to give user a functionality of file upload where user can browse for a file and upload it to server. Data stored in the file will be extracted and inserted into a table.
Frontend code:
<asp:Panel ID="panelFileUpload" runat="server">
<table>
<tr>
<td><asp:Label ID="lblFileUpload" runat="server" Text="File Upload:"></asp:Label></td>
<td><asp:FileUpload CssClass = "FileUpload" ID="fuFileUpload" runat="server" />
<asp:Button ID="btnUploadFile" runat="server" CssClass="inputButton" OnClientClick="fnStartInterval()" Text="Upload" ValidationGroup="A" />
<asp:RequiredFieldValidator ID="RFValidator" runat="server" ControlToValidate="fuFileUpload" Font-Italic="True" Display="Dynamic" ValidationGroup="A">*Please choose a file to upload! </asp:RequiredFieldValidator>
</td>
</tr>
</table>
</asp:Panel>
I found this backend code for file upload but this is not working. My Excel file has 4 cols - col1...col4. I am not sure how to map the column of Excel to table structure.
Backend code:
Protected Sub btnUploadFile_Click(sender As Object, e As EventArgs) Handles btnUploadFile.Click
Dim filename As String = Path.GetFileName(fuFileUpload.PostedFile.FileName)
Dim contentType As String = fuFileUpload.PostedFile.ContentType
Using fs As Stream = fuFileUpload.PostedFile.InputStream
Using br As New BinaryReader(fs)
Dim bytes As Byte() = br.ReadBytes(CType(fs.Length, Integer))
Dim constr As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
Using con As New SqlConnection(constr)
Dim query As String = "INSERT INTO dbo..table_1 VALUES (#ContentType, #Data)"
Using cmd As New SqlCommand(query)
cmd.Connection = con
cmd.Parameters.Add("#ContentType", SqlDbType.VarChar).Value = contentType
cmd.Parameters.Add("#Data", SqlDbType.Binary).Value = bytes
con.Open()
cmd.ExecuteNonQuery()
con.Close()
End Using
End Using
End Using
End Using
End Sub
Here, contenttype is being directly read from file. is there a way to read all 4 columns as it is and store it in table.

No promises on this but it should give you an idea on how this can be accomplished.
The DataTable is agnostic when it comes to its source so you can use the same DataTable for both the retrieved data from Excel and the insert data from to Sql Server.
Private Sub UpdateSQLServerFromExcel(FilePath As String)
Dim dt = New DataTable()
Using cnSource As New OleDbConnection($"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={FilePath};Extended Properties=""Excel 12.0 Xml;HDR=YES"";")
Using selectCommand As New OleDbCommand("Select * From [Sheet1$];", cnSource)
Using da As New OleDbDataAdapter
'The following allows the .DataRowState to remain as Added (normally it is changed to Unchanged by the .Fill method)
da.AcceptChangesDuringFill = False
da.Fill(dt)
End Using
End Using
End Using
Using cnDestination As New SqlConnection("Your Sql Server connection string")
Using selectCommand As New SqlCommand("Select * From YourSqlTableName;", cnDestination)
Using da As New SqlDataAdapter()
da.SelectCommand = selectCommand
Dim cb As New SqlCommandBuilder(da)
da.Update(dt)
End Using
End Using
End Using
End Sub

Related

VB.NET Connection string ADODB Connection (Web.Config)

I write the code below to connect database using web config but cannot connect database using ADODB to fetch data from database into textboxes
Webconfig
<connectionStrings>
<clear />
<add name="constr" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|CustomerInfor.mdb" providerName="System.Data.OleDb"/>
</connectionStrings>
SearchButton
Dim consString As String = System.Configuration.ConfigurationManager.ConnectionStrings("constr").ConnectionString
Dim objConn As New OleDbConnection(consString)
objConn.Open()
Please help with right code to fetch data from database into textboxes
Thanks
Ok, lets try this a bit different.
First up: Lets get the connection string OUT side of the code.
Like for desktop, or anything else? You can add values like connection string to the project like this:
And really nice is you get to use the connection builder to do this.
The above setting are shoved into web.config for you automatic.
So, setup your connection in above.
Ok, now in this case, I just shove on the screen a few text boxes for a user and hotel name.
Real plane jane like this:
<div style="width:25%;text-align:right;padding:25px;border:solid;border-width:1px">
<style> .tbox {width:260px;margin-left:5px;margin-bottom:15px;border-radius:8px;border-width:1px}</style>
Hotel Name: <asp:TextBox ID="txtHotelName" runat="server" class="tbox"/>
<br />
First Name: <asp:TextBox ID="txtFirst" runat="server" class="tbox" />
<br />
Last Name:<asp:TextBox ID="txtLast" runat="server" class="tbox"/>
<br />
City: <asp:TextBox ID="txtCity" runat="server" class="tbox"/>
<br />
Active:<asp:CheckBox ID="ckActive" runat="server" />
<br />
<br />
Ok, now our code to load this. I don't have a text box or source for the id, but a integer value OR a text value will work.
So, our code to load up is this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadData()
End If
End Sub
Sub LoadData()
Dim cmdSQL As OleDbCommand = New OleDbCommand()
cmdSQL.CommandText = "SELECT * from tblhotels where ID = #ID"
cmdSQL.Parameters.Add("#ID", OleDbType.Integer).Value = 23
Dim rst As DataTable = MyRst(cmdSQL)
With rst.Rows(0)
txtHotelName.Text = .Item("HotelName")
txtFirst.Text = .Item("FirstName")
txtLast.Text = .Item("LastName")
txtCity.Text = .Item("City")
ckActive.Checked = .Item("Active")
End With
ViewState("rst") = rst
End Sub
Note the cute helper routine MyRst.
So, you can use that routine EVERY where. eg:
Dim cmdSQL As OleDbCommand = New OleDbCommand("select * from RoomTypes")
Dim rst as DataTable = MyRst(cmdSQL)
So, it just a handy dandy routine. (you do NOT have to use parameters if you don't need them).
Ok, so we loaded the one row into the table (and we save that row for later use into ViewState)
Ok, so now we see this:
Now, the save code. Note how we used a record set (datatable) in place of a GAZILLION parameters.
We do this for quite a few reasons.
Strong data type conversion occurs here.
Parameter order for the save does not matter. I can cut-paste, or add 5 or 15 more columns here, and it works - and order does not matter!!!
So, now the save code.
Protected Sub cmdSave_Click(sender As Object, e As EventArgs) Handles cmdSave.Click
SaveData()
End Sub
Sub SaveData()
Dim rst As DataTable = ViewState("rst")
Using con As New OleDbConnection(My.Settings.AccessTest2)
Using cmdSQL As New OleDbCommand("SELECT * from tblHotels WHERE ID = 0", con)
Dim da As OleDbDataAdapter = New OleDbDataAdapter(cmdSQL)
Dim daSQLU As OleDbCommandBuilder = New OleDbCommandBuilder(da)
con.Open()
With rst.Rows(0)
.Item("HotelName") = txtHotelName.Text
.Item("FirstName") = txtFirst.Text
.Item("LastName") = txtLast.Text
.Item("City") = txtCity.Text
.Item("Active") = ckActive.Checked
End With
da.Update(rst)
End Using
End Using
End Sub
NOTE: not a bug, I MOST certainly did use where ID = 0
So, the nice part is we can add more text box etc. We will have to add code to setup the text boxes, but at least the order don't matter.
Last but not least?
That helper routine, the one I use to fill datatables. I even use it for say filling out combo box (dropdown lists), or whatever.
Public Function MyRst(cmdSQL As OleDbCommand) As DataTable
Dim rstData As New DataTable
Using MyCon As New OleDbConnection(My.Settings.AccessTest2)
cmdSQL.Connection = MyCon
MyCon.Open()
rstData.Load(cmdSQL.ExecuteReader)
End Using
Return rstData
End Function
So note how we used the connection string setting that we setup in the project.
And since access is sensitive to parameter order, then I adopted the above idea of using a data table. Note that this approach also works for a grid, or even adding rows. When you run that update routine? rows added, rows edits, row deleted?
They all are done for you with the ONE da.Upate(rst).
Note also, you should set your project to run as x86, and not x64, since JET ONLY can work as x32. However, the ACE data engine can be had for x64 bits.

ASP.Net object reference error when writing data to xml file via Gridview Empty data template

I have an Editable GridView control that functions off of an XML file. The GridView contains an empty-data-template given that the xml file contains no data on page load. The empty-data-template consist of two textbox controls and a link-button for placing data into the xml file, and thus should cause the Gridview to display. My problem is that when I click the link button, I get an Object-reference related error in response to this line: Dim oDr As DataRow = oDs.Tables("po").NewRow ...the full event handler, I provided below:
The code behind:
Public Sub writeStartpoNum()
Dim startpoNumID As String = DirectCast(gvPurchaseOrderNum.Controls(0).Controls(0).FindControl("txtStartpoNumID"), TextBox).Text
Dim startpoNum As String = DirectCast(gvPurchaseOrderNum.Controls(0).Controls(0).FindControl("txtStartpoNum"), TextBox).Text
Dim oDs As New DataSet()
Dim xmlPath As String = MapPath("~/xml/newShipment.xml")
If Not System.IO.File.Exists(xmlPath) Then
oDs.DataSetName = "newShipmentNotification"
oDs.Tables.Add("pos")
oDs.Tables("pos").Columns.Add("pos_Id")
oDs.Tables("pos").Columns("pos_Id").ColumnMapping = MappingType.Hidden
oDs.Tables.Add("po")
oDs.Tables("po").Columns.Add("ponumberID")
oDs.Tables("po").Columns.Add("pos_Id")
oDs.Tables("po").Columns("pos_Id").ColumnMapping = MappingType.Hidden
oDs.Tables("po").Columns.Add("ponumber")
Dim pos_po As DataRelation = oDs.Relations.Add("pos_po", oDs.Tables("pos").Columns("pos_Id"), _
oDs.Tables("po").Columns("pos_Id"))
pos_po.Nested = True
Dim oDrs As DataRow = oDs.Tables("pos").NewRow
oDrs("pos_Id") = 0
oDs.Tables("pos").Rows.Add(oDrs)
Else
oDs.ReadXml(Server.MapPath("~/xml/newShipment.xml"))
End If
Dim oDr As DataRow = oDs.Tables("po").NewRow
oDr("ponumberID") = startpoNumID
oDr("ponumber") = startpoNum
oDr("pos_Id") = 0
oDs.Tables("po").Rows.Add(oDr)
oDs.WriteXml(Server.MapPath("~/xml/newShipment.xml"))
gvPurchaseOrderNum.DataSource = oDs.Tables("po")
gvPurchaseOrderNum.DataBind()
End Sub
...this is the design for the empty-data-template in the Gridview:
<emptydatatemplate>
<b>Enter Purchase Order Number:</b> <br />
<asp:TextBox ID="txtStartpoNumID" runat="server"></asp:TextBox>
<asp:TextBox ID="txtStartpoNum" runat="server"></asp:TextBox><br />
<asp:LinkButton ID="lnkpro" runat="server" OnClick="writeStartpoNum" Text="Add Purchase order Number"></asp:LinkButton>
<br /><br />
</emptydatatemplate>
...this is how the xml reflects on page load as a results of a function that clears the xml file of any data if the xml file contains data on page load.
<?xml version="1.0" standalone="yes"?>
<newShipmentNotification>
<pos />
</newShipmentNotification>
...As I mentioned, when debugged - the issue stems from the following line
Dim oDr As DataRow = oDs.Tables("po").NewRow
The xml is build out, via the conditional statement. What I cannot figure is why the dataset variable (oDs), even though it reflects the pos table when viewed in debug mode, still generates an object-reference related error. Please provide some direction as to what I may be doing wrong here or if there is something I'm missing. Thanks
The issue is when you have the xml file without 'po' node. You can move the node to a new
method like:
Private Function CreatePOSDataset() As DataSet
Dim oDs As New DataSet()
oDs.DataSetName = "newshipmentnotification"
oDs.Tables.Add("pos")
oDs.Tables("pos").Columns.Add("pos_Id")
oDs.Tables("pos").Columns("pos_Id").ColumnMapping = MappingType.Hidden
oDs.Tables.Add("po")
oDs.Tables("po").Columns.Add("ponumberID")
oDs.Tables("po").Columns.Add("pos_Id")
oDs.Tables("po").Columns("pos_Id").ColumnMapping = MappingType.Hidden
oDs.Tables("po").Columns.Add("ponumber")
Dim pos_po As DataRelation = oDs.Relations.Add("pos_po", oDs.Tables("pos").Columns("pos_Id"), _
oDs.Tables("po").Columns("pos_Id"))
pos_po.Nested = True
Dim oDrs As DataRow = oDs.Tables("pos").NewRow
oDrs("pos_Id") = 0
oDs.Tables("pos").Rows.Add(oDrs)
CreatePOSDataset = oDs
End Function
And call the method when 'po' node does not exist:
Public Sub writeStartpoNum(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim startpoNumID As String = DirectCast(gvPurchaseOrderNum.Controls(0).Controls(0).FindControl("txtStartpoNumID"), TextBox).Text
Dim startpoNum As String = DirectCast(gvPurchaseOrderNum.Controls(0).Controls(0).FindControl("txtStartpoNum"), TextBox).Text
Dim oDs As New DataSet()
Dim xmlPath As String = MapPath("~/xml/newshipmentnotification.xml")
If Not System.IO.File.Exists(xmlPath) Then
oDs = CreatePOSDataset()
Else
oDs.ReadXml(Server.MapPath("~/xml/newshipmentnotification.xml"))
If oDs.Tables("po") Is Nothing Then
oDs = CreatePOSDataset()
End If
End If
Dim oDr As DataRow = oDs.Tables("po").NewRow
oDr("ponumberID") = startpoNumID
oDr("ponumber") = startpoNum
oDr("pos_Id") = 0
oDs.Tables("po").Rows.Add(oDr)
oDs.WriteXml(Server.MapPath("~/xml/newshipmentnotification.xml"))
gvPurchaseOrderNum.DataSource = oDs.Tables("po")
gvPurchaseOrderNum.DataBind()
End Sub

"Data type mismatch in criteria expression" error inserting Dates into Date/Time Field in Access database

I am using the Calendar extender to extend a textbox in ASP.NET inside of Visual Studio 2010. I am trying to insert the date of an event into the database along with other bits of information. I am receiving the "Data type mismatch in criteria expression" error when trying to insert into the database.
I tried using DateTime.ParseExact to convert the string date to Access Date/Time but still no luck.
Here is my code behind:
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim oleDbConn As New OleDb.OleDbConnection(ConfigurationManager.ConnectionStrings("BookMeetConnString").ConnectionString)
Dim SqlString As String = "Insert into Events(EventTitle,EventDescription,EventDate,EventCategory) Values (#f1,#f2,#f3,#f4)"
Dim cmd As OleDbCommand = New OleDbCommand(SqlString, oleDbConn)
cmd.CommandType = CommandType.Text
cmd.Parameters.AddWithValue("#f1", tb_eventtitle.Text)
cmd.Parameters.AddWithValue("#f2", tb_eventdescription.Text)
cmd.Parameters.AddWithValue("#f3", DateTime.ParseExact(tb_eventdate.Text, "dd/MM/yyyy",
CultureInfo.InvariantCulture))
cmd.Parameters.AddWithValue("#f4", dd_eventcategory.SelectedValue)
oleDbConn.Open()
cmd.ExecuteNonQuery()
System.Threading.Thread.Sleep("2000")
Response.Redirect("~/calendar.aspx")
End Sub
Here is my ASP.NET code (notice that I am also formatting the date inserted into the textbox by the CalendarExtender as "dd/MM/yyyy"):
<asp:TextBox ID="tb_eventdate" runat="server" ToolTip="Enter a
date"></asp:TextBox>
<ajaxToolkit:CalendarExtender ID="tb_eventdate_CalendarExtender" Format="dd/MM/yyyy" runat="server"
TargetControlID="tb_eventdate">
</ajaxToolkit:CalendarExtender>
The field in my Access database is of type "Date/Time".
I don't know why I am having this problem as I have managed to retrieve dates from the database in another function and converted them ToString:
Function GetEventListing(selectedDay As DateTime) As DataTable
'--read event listing for the given day from an Access query
Dim con As OleDbConnection = GetConnection()
Dim cmd As OleDbCommand = New OleDbCommand()
cmd.Connection = con
cmd.CommandText = String.Format("Select * from EventInfo Where EventDate >= #{0}# And EventDate < #{1}#", _
selectedDay.ToString("dd/MM/yyyy"), _
selectedDay.AddDays(1).ToString("dd/MM/yyyy"))
Dim ds As DataSet = New DataSet()
Dim da As OleDbDataAdapter = New OleDbDataAdapter(cmd)
da.Fill(ds)
con.Close()
Return ds.Tables(0)
End Function
What could be the cause of the error I am receiving?
Maybe it's not the date that's messing you up. I thought perhaps you were getting the error because you were adding a DateTime value as a parameter (instead of a date converted to a string formatted as yyyy-mm-dd or m/d/yyyy), but I tried the following in C# and it worked fine...
static void Main(string[] args)
{
OleDbConnection conn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Documents and Settings\Administrator\Desktop\Database1.accdb;");
conn.Open();
OleDbCommand cmd = new OleDbCommand("INSERT INTO Events (EventName, EventDate) VALUES (?, ?)", conn);
cmd.Parameters.AddWithValue("?", "TestEvent");
cmd.Parameters.AddWithValue("?", (new DateTime(2013,3,21)));
cmd.ExecuteNonQuery();
conn.Close();
Console.WriteLine("Done.");
}
...so if your DateTime parsing is returning a valid DateTime value then it looks like your query should work.
If it really is the execution of the SQL statement that is failing, the only other likely suspect is the dd_eventcategory.SelectedValue. Perhaps that needs to be .ToString()'d...?

Filter Bound Gridview to Drop Down

I've seen a couple example of how to do this by placing all the code in the aspx file, but I'm trying to do it from the code-behind. Here's what I have in the code behind:
Dim dt As New DataTable
Using conn As New OleDbConnection(ConnectionString)
conn.Open()
Dim dtAdapter As New OleDbDataAdapter
Dim command As New OleDbCommand("SELECT * FROM table " & _
"" _
, conn)
dtAdapter.SelectCommand = command
dtAdapter.Fill(dt)
conn.Close()
End Using
GridView1.DataSource = dt
GridView1.DataBind()
I'm open to any solutions, but I would prefer to do it in the code-behind if possible since thats how the rest of app is. I dont need to necessarily use a gridview just display some tabular data, so whatever works is fine. Im trying to avoid manually constructing sql strings. Any thoughts?
I don't see the question. If you don't kno how to filter the records in your query, use the Where clause with a parameter:
Dim dt = New DataTable()
Using conn As New OleDbConnection(ConnectionString)
Dim queryString As String = "SELECT * FROM Table WHERE Field1 LIKE ?"
Dim command As OleDbCommand = New OleDbCommand(queryString, conn)
command.Parameters.Add("#p1", OleDbType.Char, 3).Value = "a%"
Using da = New OleDbDataAdapter(command)
' you don't need to open/close a connection if you use DataAdapter.Fill
da.Fill(dt)
End Using
End Using
GridView1.DataSource = dt
GridView1.DataBind()
DataAdapter Parameters
Using Statement

How to write to a text file in pipe delimited format from SQL Server / ASP.Net?

I have a text file which needs to be constantly updated (regular intervals).
All I want is the syntax and possibly some code that outputs data from a SQL Server database using ASP.Net. The code I have so far is :
<%# Import Namespace="System.IO" %>
<script language="vb" runat="server">
sub Page_Load(sender as Object, e as EventArgs)
Dim FILENAME as String = Server.MapPath("Output.txt")
Dim objStreamWriter as StreamWriter
' If Len(Dir$(FILENAME)) > 0 Then Kill(FILENAME)
objStreamWriter = File.AppendText(FILENAME)
objStreamWriter.WriteLine("A user viewed this demo at: " & DateTime.Now.ToString())
objStreamWriter.Close()
Dim objStreamReader as StreamReader
objStreamReader = File.OpenText(FILENAME)
Dim contents as String = objStreamReader.ReadToEnd()
lblNicerOutput.Text = contents.Replace(vbCrLf, "<br>")
objStreamReader.Close()
end sub
</script>
<asp:label runat="server" id="lblNicerOutput" Font-Name="Verdana" />
With PHP, it is a breeze, but with .Net I have no clue. If you could help me with the database connectivity and how to write the data in pipe delimited format to an Output.txt file, that had be awesome. Thanks guys!
I would start by at least putting this code into a code-behind file so that your page at least follows the principle of least surprise.
Easiest way to write stuff to a file is to use the File.WriteAllText method (assuming your application has appropriate permissions for the file system).
You can access the database using the SqlConnection class and execute whatever commands you need with a SqlCommand. Once you've gotten data back from the database, just turn it into an array (assuming there's not a massive amount of data) and call String.Join method like so String.Join("|", yourData).
Dim dr As SqlDataReader
Dim FILENAME as String = Server.MapPath("Output.txt")
Dim objStreamWriter as StreamWriter
objStreamWriter = File.CreateText(FILENAME)
sqlConn.Open()
'opening the connection
myCommand = New SqlCommand("SELECT id, title, expirydate, creationdate from tbl where tbl.isactive=1 and getdate()<=ExpiryDate order by creationdate asc", sqlConn)
'executing the command and assigning it to connection
dr = myCommand.ExecuteReader()
While dr.Read()
objStreamWriter.WriteLine("{0}|{1}|{2:yyyy-MM-dd}|{3:yyyy-MM-dd}", dr(0), dr(1), dr(2), dr(3))
End While
dr.Close()
sqlConn.Close()
objStreamWriter.Close()
Dim objStreamReader as StreamReader
objStreamReader = File.OpenText(FILENAME)

Resources