Visual Basic - Saving textbox to Excel file - excel

I would like to setup a webpage that users can paste work orders into a textbox, click submit, and it writes it to .xlsx on a server.
I've gotten StreamWriter to save it to a .txt, but doesn't work/isn't compatible with .xlsx.
Could someone point me in the right direction? I'm not looking for someone to do it for me, but I am new to coding, so I've got tons of stupid questions.

If you had the users input the work orders into a datagrid instead of a textbox, your export to excel would be easier and look better.
Function EXPTOEXLS()
Dim rowsTotal, colsTotal As Short
Dim I, j, iC As Short
System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor
Dim xlApp As New Excel.Application 'need to add reference to "Microsoft Excel xx object library" then add | IMPORTS microsoft.office.interop (add to top)
Try
Dim excelBook As Excel.Workbook = xlApp.Workbooks.Add
Dim excelWorksheet As Excel.Worksheet = CType(excelBook.Worksheets(1), Excel.Worksheet)
xlApp.Visible = True
rowsTotal = DataGridView1.RowCount - 1
colsTotal = DataGridView1.Columns.Count - 1
With excelWorksheet
.Cells.Select()
.Cells.Delete()
For iC = 0 To colsTotal
.Cells(1, iC + 1).Value = DataGridView1.Columns(iC).HeaderText
Next
For I = 0 To rowsTotal
For j = 0 To colsTotal
.Cells(I + 2, j + 1).value = DataGridView1.Rows(I).Cells(j).Value
Next j
Next I
.Rows("1:1").Font.FontStyle = "Bold"
.Rows("1:1").Font.Size = 10
.Cells.Columns.AutoFit()
.Cells.Select()
.Cells.EntireColumn.AutoFit()
.Cells(1, 1).Select()
End With
Catch ex As Exception
MsgBox(ex.Message)
Finally
'RELEASE ALLOACTED RESOURCES
System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default
xlApp = Nothing
End Try
End Function

Related

Add an Excel Form Control to a file in vb.net

I've got an application written that does a pretty standard dump of a datagridview into an Excel file. The application loops through 12 items and creates a separate sheet in the workbook, then filling in the table using the datagridview.
The export is all good, but what I want to do now is add to every every sheet an additional column that contains a check box on every row in that sheet. It seems the better way to do that is add the form control before the Excel file is saved in the code, but I can't work out if that is possible - Adding a checkbox column to the datagridview doesn't seem to be a viable option.
Code - the dtResults is a datatable filled by a Microsoft SQL query.
Private Sub btnProcess_Click(sender As Object, e As EventArgs) Handles btnProcess.Click
Dim TestsDT As New DataTable
TestsDT.Columns.Add("SvcAbbrev")
TestsDT.Rows.Add("PH.")
TestsDT.Rows.Add("LCFA")
TestsDT.Rows.Add("FAECALP")
TestsDT.Rows.Add("PE-1")
TestsDT.Rows.Add("BGLUC")
TestsDT.Rows.Add("SIGAF")
TestsDT.Rows.Add("CALP")
TestsDT.Rows.Add("HELPFAE")
TestsDT.Rows.Add("M2-PK")
TestsDT.Rows.Add("FAEZONULIN")
TestsDT.Rows.Add("FAEFAESIGA")
Dim xlApp As Microsoft.Office.Interop.Excel.Application
Dim xlWorkBook As Microsoft.Office.Interop.Excel.Workbook
Dim xlWorkSheet As Microsoft.Office.Interop.Excel.Worksheet
Dim misValue As Object = System.Reflection.Missing.Value
Dim z As Integer
Dim x As Integer
xlApp = New Microsoft.Office.Interop.Excel.Application
xlWorkBook = xlApp.Workbooks.Add(misValue)
For l = 0 To TestsDT.Rows.Count - 1
txtTest.Text = TestsDT.Rows(l).Item("SvcAbbrev")
dgResults.DataSource = GetResults()
Dim Count As Integer = 0
Count = dgResults.Rows.Count - 1
If Count < 1 Then
Else
Dim ChkBox As New DataGridViewCheckBoxColumn()
ChkBox.HeaderText = "Checkbox"
ChkBox.Name = "Check"
dgResults.Columns.Insert(4, ChkBox)
xlWorkSheet = xlWorkBook.Sheets.Add()
xlWorkSheet.Name = txtTest.Text
xlWorkSheet.Columns.AutoFit()
For z = 0 To dgResults.RowCount - 2
For x = 0 To dgResults.ColumnCount - 1
For y As Integer = 1 To dgResults.Columns.Count
xlWorkSheet.Cells(1, y) = dgResults.Columns(y - 1).HeaderText
xlWorkSheet.Cells(z + 2, x + 1) = dgResults(x, z).Value.ToString()
Next
Next
Next
End If
Next
xlWorkBook.Sheets("Sheet1").Delete
xlWorkSheet.SaveAs("C:\Users\brettf\desktop\test-output.xlsx")
xlWorkBook.Close()
xlApp.Quit()
MessageBox.Show("Processing complete. Excel file should open automatically.", "Processing Complete", MessageBoxButtons.OK, MessageBoxIcon.Information)
Process.Start("C:\Users\brettf\desktop\test-output.xlsx")
Current Output:
Desired Output:
The checkbox has no bearing to anything in the datagridview and will be used once the document is printed by another group of staff within the business.

Export data from listview to excel vb.net

I export data from listview to excel. With this code below, it exports all the data I want to export. The problem shows when I export to excel next time. Exported data is added to previously created excel.
The code I have used is below:
Private Sub btnExcel_Click(sender As Object, e As EventArgs) Handles btnExcel.Click
Dim objExcel As New Excel.Application
Dim bkWorkBook As Excel.Workbook
Dim shWorkSheet As Excel.Worksheet
Dim i As Integer
Dim j As Integer
objExcel = New Excel.Application
bkWorkBook = objExcel.Workbooks.Add
shWorkSheet = CType(bkWorkBook.ActiveSheet, Excel.Worksheet)
For i = 0 To Me.ListView3.Columns.Count - 1
shWorkSheet.Cells(1, i + 1) = Me.ListView3.Columns(i).Text
Next
For i = 0 To Me.ListView3.Items.Count - 1
For j = 0 To Me.ListView3.Items(i).SubItems.Count - 1
shWorkSheet.Cells(i + 2, j + 1) = Me.ListView3.Items(i).SubItems(j).Text
Next
objExcel.Cells.Select()
objExcel.Cells.EntireColumn.AutoFit()
objExcel.Cells.EntireRow.AutoFit()
objExcel.Cells.Range("A1").Select()
Next
bkWorkBook.SaveAs("C:\PDF\Naročilo " + TxtPodjetje.Text + " " + DT_DatumNaročila.Text + ".xlsx")
bkWorkBook.Close()
objExcel.Quit()
If I close created vb.net app after the first export and restart it works properly and I get data as I want.
Any help would be really appreciated!

vb.net Index was out of range. Must be non-negative and less than the size of the collection

I currently have a datagridview which has an image inserted using the following code;
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim opf As New OpenFileDialog
opf.Filter = "Choose Image(*.jpg;*.png;*.gif)|*.jpg;*.png;*.gif"
If opf.ShowDialog = DialogResult.OK Then
PictureBox1.Image = Image.FromFile(opf.FileName)
End If
Try
Dim ms As New MemoryStream
PictureBox1.Image.Save(ms, PictureBox1.Image.RawFormat)
Dim img As Byte()
img = ms.ToArray()
DataGridView1.Rows.Add(img)
Catch ex As Exception
MessageBox.Show(ex.Message.ToString())
End Try
End Sub
Once clicking and selecting the image it shows in the datagridview1.
When proceeding and clicking button2 with the following code i obtain the error;
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
'Save to excel with headers
Dim ExcelApp As Object, ExcelBook As Object
Dim ExcelSheet As Object
Dim i As Integer
Dim j As Integer
'create object of excel
ExcelApp = CreateObject("Excel.Application")
ExcelBook = ExcelApp.WorkBooks.Add
ExcelSheet = ExcelBook.WorkSheets(1)
With ExcelSheet
For Each column As DataGridViewColumn In DataGridView1.Columns
.cells(1, column.Index + 1) = column.HeaderText
Next
For i = 1 To Me.DataGridView1.RowCount
.cells(i + 1, 1) = Me.DataGridView1.Rows(i - 1).Cells(i).Value
For j = 1 To DataGridView1.Columns.Count - 1
.cells(i + 1, j + 1) = DataGridView1.Rows(i - 1).Cells(j).Value
Next
Dim formatRange As Excel.Range
formatRange = ExcelSheet.Range("A1")
formatRange.EntireRow.Font.Bold = True
formatRange = ExcelSheet.Range("A1", "A1")
formatRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightBlue)
formatRange.BorderAround(Excel.XlLineStyle.xlContinuous)
formatRange = ExcelSheet.Range("a1", "A1")
formatRange.EntireRow.BorderAround()
Next
End With
ExcelApp.Visible = True
'
ExcelSheet = Nothing
ExcelBook = Nothing
ExcelApp = Nothing
Application.Exit()
End
End Sub
The form itself has the following code;
' Create Datagridview image column
Dim dgvImageColumn As New DataGridViewImageColumn
DataGridView1.Columns.Add(dgvImageColumn)
dgvImageColumn.ImageLayout = DataGridViewImageCellLayout.Stretch
Dim dgvTextColumn As New DataGridViewTextBoxColumn
DataGridView1.Columns(0).Name = "Image"
DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
DataGridView1.RowTemplate.Height = 120
DataGridView1.AllowUserToAddRows = False
When i click on proceed to save to excel it gives me the following error;
An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll
Additional information: Index was out of range. Must be non-negative and less than the size of the collection.
And the line it refers to is as follows;
.cells(i + 1, 1) = Me.DataGridView1.Rows(i - 1).Cells(i).Value
Any suggestions on how to overcome this issue?
Appreciate any support
*IMAGE ADDED TO DATAGRIDVIEW
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim opf As New OpenFileDialog
opf.Filter = "Choose Image(*.jpg;*.png;*.gif)|*.jpg;*.png;*.gif"
If opf.ShowDialog = DialogResult.OK Then
PictureBox1.Image = Image.FromFile(opf.FileName)
End If
Try
Dim ms As New MemoryStream
PictureBox1.Image.Save(ms, PictureBox1.Image.RawFormat)
Dim img As Byte()
img = ms.ToArray()
DataGridView1.Rows.Add(img)
Catch ex As Exception
MessageBox.Show(ex.Message.ToString())
End Try
End Sub
You are making the indexing more complicated than it has to be. Juggling the DIFFERENT row indexes in the DataGridView with the different row indexes in excel is complicating things. Try the simplified version below and it should work as expected.
With ExcelSheet
For Each column As DataGridViewColumn In DataGridView1.Columns
.cells(1, column.Index + 1) = column.HeaderText
Next
Dim excelRowIndex = 2
For Each row As DataGridViewRow In DataGridView1.Rows
For j = 0 To DataGridView1.Columns.Count - 1
.cells(excelRowIndex, j + 1) = row.Cells(j).Value
Next
excelRowIndex += 1
Next
Dim formatRange As Excel.Range
formatRange = ExcelSheet.Range("A1")
formatRange.EntireRow.Font.Bold = True
formatRange = ExcelSheet.Range("A1", "A1")
formatRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightBlue)
formatRange.BorderAround(Excel.XlLineStyle.xlContinuous)
formatRange = ExcelSheet.Range("a1", "A1")
formatRange.EntireRow.BorderAround()
End With
Edit to comment for error
I am confident you are getting this error because of the image/picture you are trying to (incorrectly) insert into an excel worksheet cell with the line below.
.cells(excelRowIndex, j + 1) = row.Cells(j).Value
First… you cannot add an “Image/Picture” to an excel “Cell”. You can add a shape that has an image into the worksheet. You can also, using the pictures properties have the picture move with respect to a certain cell, however, again… you cannot “directly” add an image to an excel cell as you can with the datagridview. Therefore, the line above will crash if the value in the grids cell is an image.
Second, is possibly a good reason to consider using another excel library, is that unfortunately the Excel interop library does NOT have a method to add a picture/image by passing it an “Image” object (at least that I am aware of). You can add the shape/image from a string path, but if you already have the image (as you do), then you will have to save it to a file in order to pass the image to Excel. This means, that you will have to either save the file as just described, OR keep/save each images cells path. There is a post that demonstrates how to do this using the clipboard and paste to insert the image without having the file path… How to insert picture from resources to Excel sheet, using VB2010
Neither approach above seems desirable, unfortunately if you must use interop, then you may have no choice. My understanding is that there are better open source libraries and this issue may be one of the reasons for their existence.
Lastly, whichever library you choose to use, placing the picture shapes is going to need some extra care since as I explained above, you cannot simply add the picture to a worksheet cell as you can with the DataGridView cell. This will definitely involve keeping track of where the picture shape is placed in the worksheet making sure it remains visible AND stays with its related data.
The updated code below has an Image column in column 0. When exporting this column, since I am not keeping track of the image paths the user may choose, the code simply outputs the same image. It places the image into the worksheet where: picX and picY variables define the top left corner of the picture. Each new picture is simply shifted down and to the right by 10 pixels. This is where you would need to apply the logic to tell the shape/picture which cell to stay with if rows are delete etc… . Just a though, hope it helps.
With ExcelSheet
For Each column As DataGridViewColumn In DataGridView1.Columns
.cells(1, column.Index + 1) = column.HeaderText
Next
Dim excelRowIndex = 2
Dim picX = 50
Dim picY = 50
For Each row As DataGridViewRow In DataGridView1.Rows
For j = 0 To DataGridView1.Columns.Count - 1
If (j = 0) Then
.Shapes.AddPicture("D:\Test\TestImage.jpg", Microsoft.Office.Core.MsoTriState.msoFalse,
Microsoft.Office.Core.MsoTriState.msoCTrue, picX, picY, 200, 45)
picX += 10
picY += 10
Else
.cells(excelRowIndex, j + 1) = row.Cells(j).Value
End If
Next
excelRowIndex += 1
Next
Dim formatRange As Excel.Range
formatRange = ExcelSheet.Range("A1")
formatRange.EntireRow.Font.Bold = True
formatRange = ExcelSheet.Range("A1", "A1")
formatRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightBlue)
formatRange.BorderAround(Excel.XlLineStyle.xlContinuous)
formatRange = ExcelSheet.Range("a1", "A1")
formatRange.EntireRow.BorderAround()
End With
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
'Save to excel with headers
Dim ExcelApp As Object, ExcelBook As Object
Dim ExcelSheet As Object
Dim j As Integer
Dim myOutputFile As String = "C:\Users\Desktop\Image.jpg"
PictureBox1.Image.Save(myOutputFile, System.Drawing.Imaging.ImageFormat.Jpeg)
'create object of excel
ExcelApp = CreateObject("Excel.Application")
ExcelBook = ExcelApp.WorkBooks.Add
ExcelSheet = ExcelBook.WorkSheets(1)
With ExcelSheet
For Each column As DataGridViewColumn In DataGridView1.Columns
.cells(1, column.Index + 1) = column.HeaderText
Next
Dim excelRowIndex = 2
Dim picX = 50
Dim picY = 50
For Each row As DataGridViewRow In DataGridView1.Rows
For j = 0 To DataGridView1.Columns.Count - 1
If (j = 0) Then
.Shapes.AddPicture("C:\Users\Desktop\Image.jpg", Microsoft.Office.Core.MsoTriState.msoFalse,
Microsoft.Office.Core.MsoTriState.msoCTrue, picX, picY, 200, 200)
picX += 10
picY += 10
Else
.cells(excelRowIndex, j + 1) = row.Cells(j).Value
End If
Next
excelRowIndex += 1
Next
Dim formatRange As Excel.Range
formatRange = ExcelSheet.Range("A1")
formatRange.EntireRow.Font.Bold = True
formatRange = ExcelSheet.Range("A1", "A1")
formatRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightBlue)
formatRange.BorderAround(Excel.XlLineStyle.xlContinuous)
formatRange = ExcelSheet.Range("a1", "A1")
formatRange.EntireRow.BorderAround()
End With
ExcelApp.Visible = True
'
ExcelSheet = Nothing
ExcelBook = Nothing
ExcelApp = Nothing
Application.Exit()
End
End Sub
Answered!
Thank you JohnG
Reading upon that thread you shared i used the code PictureBox1.Image.Save(SaveFilePath, System.Drawing.Imaging.ImageFormat.Jpeg)
Very Happy! Thank you for the support and guidance. Its users like you in this community that encourage me to learn and share!

Copying data from excel to pdf form, works for the first but

I want to export data from Excel to a pdf-Form using vba.
I used this approach:
https://forums.adobe.com/thread/302309
When I copy just one field it works, but I want to copy all the fields from A1:K2 where the field titles are always in the top and the content in the rows below.
I think my problem is that I don't switch back to Excel when I am trying to copy the next value and field title. But I don't know how to do it properly.
So I would be really glad if someone could tell me.
The files could be downloaded here:
http://www.xn--frank-mller-zhb.net/Formulardings.zip
Sub Pdfdings()
Dim gApp As Acrobat.CAcroApp
Dim avdoc As Acrobat.CAcroAVDoc
Dim gPDDoc As Acrobat.CAcroPDDoc
Const DOC_FOLDER As String = "C:\Users\Frank\Documents"
Dim x As Boolean
Set gApp = CreateObject("AcroExch.App")
Set gPDDoc = CreateObject("AcroExch.PDDoc")
Set avdoc = CreateObject("AcroExch.AVDoc")
'Hides Acrobat - So Far So Good
'gApp.Hide
Dim FormApp As AFORMAUTLib.AFormApp
Dim AcroForm As AFORMAUTLib.Fields
Dim Field As AFORMAUTLib.Field
Dim z, i, j, n As Integer
Dim wksTab1 As Worksheet
Dim Feld, Inhalt As String
Set wksTab1 = Sheets("Tabelle2")
'Open PDF that I choose. Acrobat still has not flashed on my screen
j = 1
i = 2
While i < 3
x = avdoc.Open(DOC_FOLDER & "\formular_ve01a.pdf", "temp")
'Acrobat Now Pops up on my screen. However, I get an error without this line. avdoc.Show works the same as Maximize it seems.
avdoc.Maximize (1)
'Hides it again, right after it opens. This creates a flash
'gApp.Hide
Set FormApp = CreateObject("AFormAut.App")
While j < 39
'If the Maximize line is not there, this is where I receive error about document viewer
Feld = wksTab1.Cells(1, j).Value
Inhalt = wksTab1.Cells(i, j).Value
For Each Field In FormApp.Fields
If Field.Name = Feld Then
Field.Value = Inhalt
End If
Next
j = j + 1
Wend
Dim sDoc
Set sDoc = avdoc.GetPDDoc
saveOk = sDoc.Save(1, DOC_FOLDER & "\OK_Formular" & wksTab1.Cells(1, 1).Value & ".pdf")
avdoc.Close (1)
gApp.Exit
i = i + 1
Wend
End Sub
Set A1:K2 as your print range
Set your printer to a PDF Writer (CutePDF or PDF995 or other)
Print
solution I got by the help of another forum
<pre>While j < 39
'If the Maximize line is not there, this is where I receive error about document viewer
Feld = wksTab1.Cells(1, j).Value
Inhalt = wksTab1.Cells(i, j).Value
FormApp.Fields(Feld).Value = Inhalt
j = j + 1
Wend
Thank you everyone!

Transfering shape data from Visio 2010 to Excel 2010 for further manipulation using VBA

I'm attempting to take shape data (withing specific shapes) and transfer their values into an Excel spreadsheet so that Excel can run functions on the transferred values.
The plan is to click on a shape and automatically send its specific shape data to Excel, where it will be manipulated further to create a very specific spreadsheet.
I'm using VBA for all the programming.
I know how to acquire shape data and manipulate it WITHIN Visio but I'm not sure how to pass it to Excel.
So, is this even possible? I know you can link shapes to data (which I've done) and hyperlink shapes to specific documents (which I've also done) but is it possible to send specific shape data to a document for further manipulation?
Please help, I've not been able to find any information on this situation anywhere.
Thank you in advance!
Yes it is possible. Here is some VBA code to create an Excel report from Visio.
Just remember that Excel VBA and Visio VBA have properties with the same name so make sure you fully qualify the Excel reference. Otherwise VBA gets confused.
Public Sub ExcelReport()
Dim shpsObj As Visio.Shapes, shpObj As Visio.Shape
Dim celObj1 As Visio.Cell, celObj2 As Visio.Cell
Dim curShapeIndx As Integer
Dim localCentx As Double, localCenty As Double, localCenty1 As Double
Dim ShapesCnt As Integer, i As Integer
Dim ShapeHeight As Visio.Cell, ShapeWidth As Visio.Cell
Dim XlApp As Excel.Application
Dim XlWrkbook As Excel.Workbook
Dim XlSheet As Excel.Worksheet
Set XlApp = CreateObject("excel.application")
' You may have to set Visible property to True if you want to see the application.
XlApp.Visible = True
Set XlWrkbook = XlApp.Workbooks.Add
Set XlSheet = XlWrkbook.Worksheets("sheet1")
Set shpObjs = ActivePage.Shapes
ShapesCnt = shpObjs.Count
XlSheet.Cells(1, 1) = "Indx"
XlSheet.Cells(1, 2) = "Name"
XlSheet.Cells(1, 3) = "Text"
XlSheet.Cells(1, 4) = "localCenty"
XlSheet.Cells(1, 5) = "localCentx"
XlSheet.Cells(1, 6) = "Width"
XlSheet.Cells(1, 7) = "Height"
' Loop through all the shapes on the page to find their locations
For curShapeIndx = 1 To ShapesCnt
Set shpObj = shpObjs(curShapeIndx)
If Not shpObj.OneD Then
Set celObj1 = shpObj.Cells("pinx")
Set celObj2 = shpObj.Cells("piny")
localCentx = celObj1.Result("inches")
localCenty = celObj2.Result("inches")
Set ShapeWidth = shpObj.Cells("Width")
Set ShapeHeight = shpObj.Cells("Height")
Debug.Print shpObj.Name, shpObj.Text, curShapeIndx; Format(localCenty, "000.0000") & " " & Format(localCentx, "000.0000"); " "; ShapeWidth; " "; ShapeHeight
i = curShapeIndx + 1
XlSheet.Cells(i, 1) = curShapeIndx
XlSheet.Cells(i, 2) = shpObj.Name
XlSheet.Cells(i, 3) = shpObj.Text
XlSheet.Cells(i, 4) = localCenty
XlSheet.Cells(i, 5) = localCentx
XlSheet.Cells(i, 6) = ShapeWidth
XlSheet.Cells(i, 7) = ShapeHeight
End If
Next curShapeIndx
XlApp.Quit ' When you finish, use the Quit method to close
Set XlApp = Nothing '
End Sub
John... Visio MVP

Resources