is there a way to get a specific cell in excel using this code ?.
Try
OpenFileDialog.InitialDirectory = "Desktop"
OpenFileDialog.Filter = "All Files (*.*)|*.*|Excel Files (*.xlsx)|*.xlsx|Xls Files (*.xls)|*.xls"
If OpenFileDialog.ShowDialog(Me) = System.Windows.Forms.DialogResult.OK Then
Dim fi As New IO.FileInfo(OpenFileDialog.FileName)
Dim Filename As String = OpenFileDialog.FileName
excel = fi.FullName
conn = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excel + ";Extended Properties=Excel 12.0;")
dta = New OleDbDataAdapter("select * from [Sheet1$]", conn)
dts = New DataSet
dta.Fill(dts, "Sheet1$")
DGV1.DataSource = dts
DGV1.DataMember = "Sheet1$"
conn.Close()
End If
lblRowCount.Text = DGV1.Rows.Count - 1
Catch ex As Exception
MsgBox(ex.Message)
conn.Close()
Exit Sub
End Try
or is there a other way to import excel files to datagridview using loop inserting cell by cell ?.
You can print the C2 cell value with this code
'-------- Option Strict off ---------------
Private Sub Button13_Click(sender As Object, e As EventArgs) Handles Button13.Click
Dim mypath As String
Dim xlApp As New Excel.Application
Dim wb As Excel.Workbook
Dim ws As Excel.Worksheet
mypath = "F:\Documents\myfile.xlsx"
wb = xlApp.Workbooks.Open(mypath)
ws = xlApp.Worksheets(1)
MessageBox.Show(ws.cells(2, 3).value + " in cell C2")
wb.Close()
xlApp.Quit()
End Sub
' --------- option strict on ------------------
Private Sub Button13_Click(sender As Object, e As EventArgs) Handles Button13.Click
Dim percorso As String
Dim xlApp As New Excel.Application
Dim wb As Excel.Workbook
Dim ws As Excel.Worksheet
mypath = "F:\Documents\myfile.xlsx"
wb = xlApp.Workbooks.Open(mypath)
ws = CType(xlApp.Worksheets(1), Excel.Worksheet)
Dim xRng As Excel.Range = CType(ws.Cells(2, 3), Excel.Range)
Dim val As Object = xRng.Value()
MessageBox.Show(val.ToString + " in cell C2")
wb.Close()
xlApp.Quit()
End Sub
Related
Im fairly new to VB 2013. Any advice and help is greatly appreciated.
I have a datagridview that I want to export to Excel. I have the code working that does the export, but it doesnt show the header names. I need to edit the code to bring the header names over as well.
Additionally, I want to drop the first column from the export.
Example of my gridview code:
Private Sub Button2_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button2.Click
Dim xlApp As Excel.Application
Dim xlWorkBook As Excel.Workbook
Dim xlWorkSheet As Excel.Worksheet
Dim misValue As Object = System.Reflection.Missing.Value
Dim i As Integer
Dim j As Integer
xlApp = New Excel.Application
xlWorkBook = xlApp.Workbooks.Add(misValue)
xlWorkSheet = xlWorkBook.Sheets("Sheet1")
'Export Header Names Start
Dim columnsCount As Integer = DataGridView1.Columns.Count
For Each column In DataGridView1.Columns
xlWorkSheet.Cells(1, column.Index + 1).Value = column.name
Next
' 'Export Header Name End
For i = 0 To DataGridView1.RowCount - 2
For j = 0 To DataGridView1.ColumnCount - 1
xlWorkSheet.Cells(i + 1, j + 1) = _
DataGridView1(j, i).Value.ToString()
Next
Next
If System.IO.File.Exists("C:\test\export.xlsx") Then
System.IO.File.Delete("C:\test\export.xlsx")
End If
xlWorkSheet.SaveAs("C:\test\export.xlsx")
xlWorkBook.Close()
xlApp.Quit()
releaseObject(xlApp)
releaseObject(xlWorkBook)
releaseObject(xlWorkSheet)
MsgBox("You can find the file here C:\test")
End Sub
DataGridview Output:
For many years i,m using this function.
Public Sub grid_ToExcel_Export(ByVal FileName As String, ByVal Data_GridView As DataGridView)
Dim sb As New System.Text.StringBuilder
Try
Dim intColumn, intColumnValue As Integer
Dim row As DataGridViewRow
For intColumn = 0 To Data_GridView.Columns.Count - 1
sb.Append(Data_GridView.Columns(intColumn).HeaderText)
If intColumnValue <> Data_GridView.Columns.Count - 1 Then
sb.Append(vbTab)
End If
Next
sb.Append(vbCrLf)
For Each row In Data_GridView.Rows
For intColumnValue = 0 To Data_GridView.Columns.Count - 1
sb.Append(StrConv(IIf(IsDBNull(row.Cells(intColumnValue).Value), "", row.Cells(intColumnValue).Value), VbStrConv.None))
If intColumnValue <> Data_GridView.Columns.Count - 1 Then
sb.Append(vbTab)
End If
Next
sb.Append(vbCrLf)
Next
SaveExcel(FileName, sb)
Catch ex As Exception
Throw
Finally
Data_GridView = Nothing
sb = Nothing
End Try
End Sub
Private Sub SaveExcel(ByVal fpath As String, ByVal sb As System.Text.StringBuilder)
Dim fsFile As New FileStream(fpath, FileMode.Create, FileAccess.Write)
Dim strWriter As New StreamWriter(fsFile, System.Text.Encoding.Unicode)
Try
With strWriter
.BaseStream.Seek(0, SeekOrigin.End)
.WriteLine(sb)
.Close()
End With
Catch e As Exception
msg(e.ToString)
Finally
sb = Nothing
strWriter = Nothing
fsFile = Nothing
End Try
End Sub
I have this program where I am trying to upload an excel file and will be shown in my datagridview but i having this error
Additional information: Could not find installable ISAM.
Im new to VB please help me
Here is my code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Con As System.Data.OleDb.OleDbConnection
Dim ds As System.Data.DataSet
Dim cmd As System.Data.OleDb.OleDbDataAdapter
Con = New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0;Data Source='c:\manpower.xlsx';Extended Properties=cc;")
cmd = New System.Data.OleDb.OleDbDataAdapter("select * from [Sheet2$]", Con)
ds = New System.Data.DataSet
cmd.Fill(ds)
DataGridView1.DataSource = ds.Tables(0)
Con.Close()
End Sub
Why are you using OLEDB connection in the first place? Why not sqlConnection?
If you can, use something like this:
Private Sub LoadFormData()
Dim cmdText as String
Dim ds as DataSet
cmdText = "SELECT ID, FName, SName, Title FROM PeopleTable;"
ds = GetQueryResults(cmdText)
Me.DataGridView1.DataSource = ds.Tables(0)
End Sub
Private Function GetQueryResults(cmdText As String)
Dim oConn As New SqlConnection
oConn.ConnectionString = "........." ' your connection string
Dim cmd As New SqlCommand(cmdText, oConn)
Dim ds As New DataSet()
Dim da As New SqlDataAdapter(cmd)
Try
oConn.Open()
da.Fill(ds)
oConn.Close()
Catch ex As Exception ' handle error any way you like
Dim errform As New SysErrScreen
errform.ErrText.Text = ex.Message & vbCrLf & vbCrLf & cmdText
errform.ShowDialog()
oConn.Close()
End Try
Return ds
End Function
You can easily import an Excel file into DataGridView, and export from DataGridView to Excel.
Imports Excel = Microsoft.Office.Interop.Excel
Imports System.Data.OleDb
'~~> Define your Excel Objects
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim xlApp As New Excel.Application
'Dim xlWorkBook As Excel.Workbook
'Dim xlWorkSheet As Excel.Worksheet
Dim strConn As String
Dim da As OleDbDataAdapter
Dim ds As New DataSet
Dim dao_dbE As dao.DBEngine
Dim dao_DB As DAO.Database
Dim strFirstSheetName As String
dao_dbE = New dao.DBEngine
dao_DB = dao_dbE.OpenDatabase("C:\your_path_here\Book1.xls", False, True, "Excel 8.0;")
strFirstSheetName = dao_DB.TableDefs(0).Name
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\your_path_here\Book1.xls;Extended Properties=""Excel 8.0;"""
da = New OleDbDataAdapter("SELECT * FROM [" & _
strFirstSheetName & "]", strConn)
da.TableMappings.Add("Table", "Excel")
da.Fill(ds)
DataGridView1.DataSource = ds.Tables(0).DefaultView
da.Dispose()
dao_DB.Close()
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
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
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 - 1
For j = 0 To colsTotal - 1
.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("Export Excel Error " & ex.Message)
Finally
'RELEASE ALLOACTED RESOURCES
System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default
xlApp = Nothing
End Try
End Sub
Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
Dim xlApp As Excel.Application
Dim xlWorkBook As Excel.Workbook
Dim xlWorkSheet As Excel.Worksheet
Dim misValue As Object = System.Reflection.Missing.Value
Dim i As Integer
Dim j As Integer
xlApp = New Excel.Application
xlWorkBook = xlApp.Workbooks.Add(misValue)
xlWorkSheet = xlWorkBook.Sheets("sheet1")
For Each col As DataGridViewColumn In Me.DataGridView1.Columns
xlWorkSheet.Cells(1, col.Index + 1) = col.HeaderText.ToString
Next
Try
For CurrentRowIndex = 0 To DataGridView1.RowCount - 1 'current row index
'For j = 0 To Me.DataGridView1.ColumnCount
For CurrentColumnIndex = 0 To DataGridView1.ColumnCount - 1 'current column index within row index
xlWorkSheet.Cells(2, CurrentColumnIndex + 1) = DataGridView1.Columns(CurrentColumnIndex).HeaderText 'display header
xlWorkSheet.Cells(CurrentRowIndex + 3, CurrentColumnIndex + 1) = DataGridView1(CurrentColumnIndex, CurrentRowIndex).Value.ToString()
Next
'xlWorkSheet.Cells(2, CurrentColumnIndex + 1) = DataGridView1.Columns(CurrentColumnIndex).HeaderText 'display header
'xlWorkSheet.Cells(i + 2, j + 1) = Me.DataGridView1(j, i).Value.ToString()
'xlWorkSheet.Cells(2, CurrentColumnIndex + 1) = DataGridView1.Columns(CurrentColumnIndex).HeaderText 'display header
'Next
Next
Catch ex As Exception
MsgBox("Unable to extract data" & ex.Message, MsgBoxStyle.Critical)
Exit Sub
End Try
xlWorkBook.Activate()
'//get path
Me.FolderBrowserDialog1.ShowDialog()
Dim path As String = Me.FolderBrowserDialog1.SelectedPath
xlWorkBook.SaveAs(path & "\Excel_With_Headers.xls")
'xlWorkSheet.SaveAs("burn permit export.xls")
xlWorkBook.Close()
xlApp.Quit()
'releaseObject(xlApp)
'releaseObject(xlWorkBook)
'releaseObject(xlWorkSheet)
MsgBox("You can find your report at " & path & "\burn permit export.xls")
End Sub
Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
Dim xlApp As Excel.Application
Dim xlWorkBook As Excel.Workbook
Dim xlWorkSheet As Excel.Worksheet
Dim misValue As Object = System.Reflection.Missing.Value
Dim i As Integer
Dim j As Integer
xlApp = New Excel.Application
xlWorkBook = xlApp.Workbooks.Add(misValue)
xlWorkSheet = xlWorkBook.Sheets("sheet1")
Try
For CurrentRowIndex = 0 To DataGridView1.RowCount - 1 'current row index
'xlWorkSheet.Cells(1, 1) = "With Headers"
For CurrentColumnIndex = 0 To DataGridView1.ColumnCount - 1 'current column index within row index
xlWorkSheet.Cells(2, CurrentColumnIndex + 1) = DataGridView1.Columns(CurrentColumnIndex).HeaderText 'display header
xlWorkSheet.Cells(CurrentRowIndex + 3, CurrentColumnIndex + 1) = DataGridView1(CurrentColumnIndex, CurrentRowIndex).Value.ToString()
Next
Next
Catch ex As Exception
MsgBox("Unable to extract data" & ex.Message, MsgBoxStyle.Critical)
Exit Sub
End Try
End Sub
End Class
Can anyone point out what is causing the excel process to remain open after my code finishes?
I've researched everything on this topic and the main point seems to be to avoid 3 dots with excel interop, but I believe I have done that and I still can't see where I'm going wrong.
my process is to copy the datagridview to the clipboard and then paste it in a newly created excel file, save it, close excel, and then give the user an option to open the file.
Two scenarios. First, when I run through the code and DON'T open the excel file it leaves the process open. Second, if I open the workbook and then close the workbook it doesn't leave a process running. I don't understand the difference because the opening of the workbook happens after I try to close and release all references to excel.
Private Sub CopyDGVtoClipBoard()
Me.DataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText
Me.DataGridView1.RowHeadersVisible = False
Me.DataGridView1.SelectAll()
Dim dataObj As DataObject = Me.DataGridView1.GetClipboardContent
If dataObj IsNot Nothing Then
Clipboard.SetDataObject(dataObj)
End If
Me.DataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithAutoHeaderText
Me.DataGridView1.RowHeadersVisible = True
Me.DataGridView1.ClearSelection()
End Sub
Private Sub ExportToExcel()
If Me.DataGridView1.Rows.Count < 1 Then Exit Sub
CopyDGVtoClipBoard()
SaveFileDialog1.Filter = "Excel File|*.xlsx"
SaveFileDialog1.Title = "Save In"
SaveFileDialog1.FileName = "Generic name"
If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
If SaveFileDialog1.FileName <> "" Then
Dim xlExcel As excel.Application
Dim xlWorkBooks As excel.Workbooks
Dim xlWorkBook As excel.Workbook
Dim xlWorkSheet As excel.Worksheet
Dim CR As excel.Range
Dim misValue As Object = System.Reflection.Missing.Value
xlExcel = New excel.Application
xlExcel.Visible = True
xlWorkBooks = xlExcel.Workbooks
xlWorkBook = xlWorkBooks.Add(misValue)
xlWorkBook.Application.DisplayAlerts = False
xlWorkSheet = xlWorkBook.ActiveSheet
CR = xlWorkSheet.Cells(1, 1)
CR.Select()
xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, True)
xlWorkBook.SaveAs(SaveFileDialog1.FileName())
xlWorkBook.Close(False)
misValue = Nothing
ReleaseExcel(CR)
ReleaseExcel(xlWorkSheet)
ReleaseExcel(xlWorkBook)
ReleaseExcel(xlWorkBooks)
xlExcel.Quit()
ReleaseExcel(xlExcel)
Dim OpenCheck As MsgBoxResult = MsgBox("Would you like to open the file?", MsgBoxStyle.YesNo, "Open File")
Dim fPath As String = SaveFileDialog1.FileName
If OpenCheck = MsgBoxResult.Yes Then
Process.Start(fPath)
End If
End If
End If
Private Sub ReleaseExcel(ByVal O As Object)
Do While System.Runtime.InteropServices.Marshal.ReleaseComObject(O) >= 0
System.Runtime.InteropServices.Marshal.ReleaseComObject(O)
Loop
O = Nothing
End Sub
I've narrowed the issue down to the below code. If I do everything except specifying a range and adding data it'll close and end the process but as soon as I reference CR = xlWorkSheet.Cells(1,1) it hangs a process
CR = xlWorkSheet.Cells(1, 1)
CR.Select()
xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, True)
Edit
So I compared my code vs. what Karen posted and made some slight adjustments to my code (full code plus changes listed below), but for some reason it works and doesn't leave a process open! Not sure how, but I'll take it.
Private Sub CopyDGVtoClipBoard()
Me.DataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText
Me.DataGridView1.RowHeadersVisible = False
Me.DataGridView1.SelectAll()
Dim dataObj As DataObject = Me.DataGridView1.GetClipboardContent
If dataObj IsNot Nothing Then
Clipboard.SetDataObject(dataObj)
End If
Me.DataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithAutoHeaderText
Me.DataGridView1.RowHeadersVisible = True
Me.DataGridView1.ClearSelection()
End Sub
Private Sub ExportToExcel()
If Me.DataGridView1.Rows.Count < 1 Then Exit Sub
CopyDGVtoClipBoard()
Dim DateCon As DateTime = DateTime.ParseExact(Today.ToShortDateString, "M/d/yyyy", Nothing)
SaveFileDialog1.Filter = "Excel File|*.xlsx"
SaveFileDialog1.Title = "Save In"
SaveFileDialog1.FileName = "Generic Name"
If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
If SaveFileDialog1.FileName <> "" Then
Dim xlExcel As excel.Application = Nothing
Dim xlWorkBooks As excel.Workbooks = Nothing
Dim xlWorkBook As excel.Workbook = Nothing
Dim xlWorkSheet As excel.Worksheet = Nothing
Dim CR As excel.Range = Nothing
Dim misValue As Object = System.Reflection.Missing.Value
xlExcel = New excel.Application
xlExcel.Visible = False
xlExcel.DisplayAlerts = False
xlWorkBooks = xlExcel.Workbooks
xlWorkBook = xlWorkBooks.Add(misValue)
xlWorkSheet = xlWorkBook.ActiveSheet
CR = xlWorkSheet.Range("A1")
CR.PasteSpecial(excel.XlPasteType.xlPasteAll)
CR.Select()
xlWorkBook.SaveAs(SaveFileDialog1.FileName)
Clipboard.Clear()
ReleaseExcel(CR)
CR = Nothing
ReleaseExcel(xlWorkSheet)
xlWorkSheet = Nothing
xlWorkBook.Close(False)
ReleaseExcel(xlWorkBook)
xlWorkBook = Nothing
ReleaseExcel(xlWorkBooks)
xlWorkBooks = Nothing
xlExcel.Quit()
ReleaseExcel(xlExcel)
xlExcel = Nothing
Dim OpenCheck As MsgBoxResult = MsgBox("Would you like to open the file?", MsgBoxStyle.YesNo, "Open File")
Dim fPath As String = SaveFileDialog1.FileName
If OpenCheck = MsgBoxResult.Yes Then
Process.Start(fPath)
End If
End If
End If
End Sub
Private Sub ReleaseExcel(ByVal O As Object)
Try
Do Until System.Runtime.InteropServices.Marshal.FinalReleaseComObject(O) = 0
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(O)
Loop
Catch ex As Exception
Finally
GC.Collect()
GC.WaitForPendingFinalizers()
End Try
End Sub
The following goes along with using only two dots. After the work is done excel is properly disposed of.
Option Strict On
Option Infer Off
Imports Excel = Microsoft.Office.Interop.Excel
Imports Microsoft.Office
Imports System.Runtime.InteropServices
Module Demo1
Public Sub DoPaste()
Dim FileName As String = IO.Path.Combine(Application.StartupPath, "SomeFile.xlsx")
Dim SheetName As String = "Sheet1"
Dim Proceed As Boolean = False
Dim xlApp As Excel.Application = Nothing
Dim xlWorkBooks As Excel.Workbooks = Nothing
Dim xlWorkBook As Excel.Workbook = Nothing
Dim xlWorkSheet As Excel.Worksheet = Nothing
Dim xlWorkSheets As Excel.Sheets = Nothing
Dim xlCells As Excel.Range = Nothing
xlApp = New Excel.Application
xlApp.DisplayAlerts = False
xlWorkBooks = xlApp.Workbooks
xlWorkBook = xlWorkBooks.Open(FileName)
xlApp.Visible = False
xlWorkSheets = xlWorkBook.Sheets
For x As Integer = 1 To xlWorkSheets.Count
xlWorkSheet = CType(xlWorkSheets(x), Excel.Worksheet)
If xlWorkSheet.Name = SheetName Then
Dim xlRange1 As Excel.Range = Nothing
xlRange1 = xlWorkSheet.Range("A1:B6")
xlRange1.Select()
xlRange1.Copy()
Dim xlDestination As Excel.Range = Nothing
xlDestination = xlWorkSheet.Range("C1:D6")
xlDestination.PasteSpecial(Excel.XlPasteType.xlPasteAll, Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone)
Marshal.FinalReleaseComObject(xlDestination)
xlDestination = Nothing
Marshal.FinalReleaseComObject(xlRange1)
xlRange1 = Nothing
xlWorkSheet.SaveAs(FileName)
Marshal.FinalReleaseComObject(xlWorkSheet)
xlWorkSheet = Nothing
Exit For
End If
Next
xlWorkBook.Close()
xlApp.UserControl = True
xlApp.Quit()
ReleaseComObject(xlCells)
ReleaseComObject(xlWorkSheets)
ReleaseComObject(xlWorkSheet)
ReleaseComObject(xlWorkBook)
ReleaseComObject(xlWorkBooks)
ReleaseComObject(xlApp)
End Sub
Private Sub ReleaseComObject(ByVal obj As Object)
Try
If obj IsNot Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
obj = Nothing
End If
Catch ex As Exception
obj = Nothing
End Try
End Sub
End Module
I am trying to figure how to set the active workbook and active sheet as a variable I can reference later. I have my script set up, and I placed ????'s in the areas where I assume I would put the reference.
Any suggetsions?
Dim oXL As Application
Dim oWB As Microsoft.Office.Interop.Excel.Workbook
Dim oSheet As Microsoft.Office.Interop.Excel.Worksheet
Dim oRng As Microsoft.Office.Interop.Excel.Range
oWB = ????
oSheet = ?????
Added info from comment to Karen Payne's answer:
I am trying to reference an existing one I already have open, that is
the active window at the time of using my application.
i.e.: How can I attach to an open Excel instance and retrieve a reference to the ActiveWorkbook?
Perhaps the following will help. It is a demo that sets the active sheet in xlWorkSheet that can be used as you see fit.
Option Strict On
Imports Excel = Microsoft.Office.Interop.Excel
Imports Microsoft.Office
Imports System.Runtime.InteropServices
Module SetDefaultWorkSheetCode
Public Sub SetDefaultSheet(ByVal FileName As String, ByVal SheetName As String)
Dim xlApp As Excel.Application = Nothing
Dim xlWorkBooks As Excel.Workbooks = Nothing
Dim xlWorkBook As Excel.Workbook = Nothing
Dim xlWorkSheet As Excel.Worksheet = Nothing
Dim xlWorkSheets As Excel.Sheets = Nothing
xlApp = New Excel.Application
xlApp.DisplayAlerts = False
xlWorkBooks = xlApp.Workbooks
xlWorkBook = xlWorkBooks.Open(FileName)
xlApp.Visible = False
xlWorkSheets = xlWorkBook.Sheets
For x As Integer = 1 To xlWorkSheets.Count
xlWorkSheet = CType(xlWorkSheets(x), Excel.Worksheet)
If xlWorkSheet.Name = SheetName Then
xlWorkSheet.Activate()
xlWorkSheet.SaveAs(FileName)
Runtime.InteropServices.Marshal.FinalReleaseComObject(xlWorkSheet)
xlWorkSheet = Nothing
Exit For
End If
Runtime.InteropServices.Marshal.FinalReleaseComObject(xlWorkSheet)
xlWorkSheet = Nothing
Next
xlWorkBook.Close()
xlApp.UserControl = True
xlApp.Quit()
ReleaseComObject(xlWorkSheets)
ReleaseComObject(xlWorkSheet)
ReleaseComObject(xlWorkBook)
ReleaseComObject(xlWorkBooks)
ReleaseComObject(xlApp)
End Sub
Private Sub ReleaseComObject(ByVal obj As Object)
Try
If obj IsNot Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
obj = Nothing
End If
Catch ex As Exception
obj = Nothing
End Try
End Sub
End Module
With those Excel objects, you have to assign values to them using the "Set" keyword. For example:
Set oWB = ActiveWorkbook
Here are two techniques for attaching to a running Excel instance. I think the method shown in 'Button1_Click' is one you are seeking, but I also showed second method that looks in the Running Object Table (ROT) for a matching Workbook name.
Imports System.Runtime.InteropServices
Imports Microsoft.Office.Interop
Public Class Form1
Private WithEvents ExcelCleanUpTimer As New Timer With {.Interval = 100}
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim app As Excel.Application
Try ' to attach to any Excel instance
app = CType(Marshal.GetActiveObject("Excel.Application"), Excel.Application)
Catch ex As Exception
MessageBox.Show("No Excel instances found")
Exit Sub
End Try
' take over responsibility for closing Excel
app.UserControl = False
app.Visible = False
Dim activeWB As Excel.Workbook = app.ActiveWorkbook
Dim activeSheet As Object = app.ActiveSheet
' determine if ActiveSheet is a Worksheet or Chart
' if it is a Worksheet, activeChart is Nothing
' if it is a Chart, activeWorksheet is Nothing
Dim activeWorksheet As Excel.Worksheet = TryCast(activeSheet, Excel.Worksheet)
Dim activeChart As Excel.Chart = TryCast(activeSheet, Excel.Chart)
If activeWorksheet IsNot Nothing Then
For Each cell As Excel.Range In activeWorksheet.Range("A1:A20")
cell.Value2 = "hello"
Next
End If
'shut Excel down, don't save anything
app.DisplayAlerts = False
app.Workbooks.Close()
app.Quit()
' using a timer lets any ComObj variables in this method go out of context and
' become eligible for finalization. GC's call to RCW wrapper finalizer will
' release its reference counts on Excel
ExcelCleanUpTimer.Start()
End Sub
Private Sub ExcelCleanUpTimer_Tick(sender As Object, e As EventArgs) Handles ExcelCleanUpTimer.Tick
ExcelCleanUpTimer.Stop()
GC.Collect()
GC.WaitForPendingFinalizers()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
' if this is a saved Workbook, the path will be the full file path
Dim path As String = "Book1" ' or the full file path to a workbook including the extension
Dim activeWorkbook As Excel.Workbook = Nothing
Try
' this technique differs for Marshal.GetActiveObject in that if the path
' is a valid file path to an Excel file and Excel is not running, it will
' launch Excel to open the file.
activeWorkbook = CType(Marshal.BindToMoniker(path), Excel.Workbook)
Catch ex As Exception
' an exception will be throw if 'path' is not found in the Runinng Object Table (ROT)
MessageBox.Show(path & " not found")
Exit Sub
End Try
Dim app As Excel.Application = activeWorkbook.Application
app.Visible = True
app.UserControl = True
' the wb window will be hidden if opening a file
activeWorkbook.Windows(1).Visible = True
ExcelCleanUpTimer.Start()
End Sub
End Class
Sorry about my last answer.. I didn't see that you were trying to do it in .NET. Anyway, just like in the context of Excel, you have to first open or create all of the workbooks that you want to work with. If you already have it open, then you can use the file name of the workbook you want to assign it to a workbook variable..
xlWorkbook = xlApp.Workbooks.Item("filename of the workbook already open")
Here is the same code, partly commented out as to the activate part and I added in code to show how to get the current active sheet.
Option Strict On
Imports Excel = Microsoft.Office.Interop.Excel
Imports Microsoft.Office
Imports System.Runtime.InteropServices
Module SheetCode
Public Sub SetDefaultSheet(ByVal FileName As String, ByVal SheetName As String)
Dim xlApp As Excel.Application = Nothing
Dim xlWorkBooks As Excel.Workbooks = Nothing
Dim xlWorkBook As Excel.Workbook = Nothing
Dim xlWorkSheet As Excel.Worksheet = Nothing
Dim xlWorkSheets As Excel.Sheets = Nothing
xlApp = New Excel.Application
xlApp.DisplayAlerts = False
xlWorkBooks = xlApp.Workbooks
xlWorkBook = xlWorkBooks.Open(FileName)
xlApp.Visible = False
xlWorkSheets = xlWorkBook.Sheets
'
' Here I added how to get the current active worksheet
'
Dim ActiveSheetInWorkBook As Excel.Worksheet = CType(xlWorkBook.ActiveSheet, Excel.Worksheet)
Console.WriteLine(ActiveSheetInWorkBook.Name)
Runtime.InteropServices.Marshal.FinalReleaseComObject(ActiveSheetInWorkBook)
ActiveSheetInWorkBook = Nothing
'For x As Integer = 1 To xlWorkSheets.Count
' xlWorkSheet = CType(xlWorkSheets(x), Excel.Worksheet)
' If xlWorkSheet.Name = SheetName Then
' xlWorkSheet.Activate()
' xlWorkSheet.SaveAs(FileName)
' Runtime.InteropServices.Marshal.FinalReleaseComObject(xlWorkSheet)
' xlWorkSheet = Nothing
' Exit For
' End If
' Runtime.InteropServices.Marshal.FinalReleaseComObject(xlWorkSheet)
' xlWorkSheet = Nothing
'Next
xlWorkBook.Close()
xlApp.UserControl = True
xlApp.Quit()
ReleaseComObject(xlWorkSheets)
ReleaseComObject(xlWorkSheet)
ReleaseComObject(xlWorkBook)
ReleaseComObject(xlWorkBooks)
ReleaseComObject(xlApp)
End Sub
Private Sub ReleaseComObject(ByVal obj As Object)
Try
If obj IsNot Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
obj = Nothing
End If
Catch ex As Exception
obj = Nothing
End Try
End Sub
End Module
I had this code working a few days ago, but forgot to save the working copy. It took me 4 weeks just to find this answer and would not like to take that much time again, so...
Everything here works, except the objWorkBook lines, which return the error:
"Variable 'objWorkBook' is used before it has been assigned a value. A null reference exception could result at runtime."
Any suggestions?
Dim objExcel As Excel.Application = System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application")
Dim objWorkBook As Excel.Workbook
Dim totalWorkBooks As Integer = objExcel.Workbooks.Count
MsgBox(totalWorkBooks & " is Number of Open Workbooks")
Dim ActiveBookIndex As Integer = objExcel.ActiveWindow.Index
MsgBox(ActiveBookIndex & " is Active Window Index")
Dim FullName As String = objWorkBook.FullName
MsgBox(FullName & " is FullName")
Dim OnlyName As String = objWorkBook.Name
MsgBox(OnlyName & " is Name without the Path")
I forgot what Value I had assigned.
My objective is to compare an open Excel Workbook name with one in a known location so that if they match, my program can proceed. I need the code above so I can compare it to the following code in an If-Then so that my program can proceed.
Dim dir As String = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
Dim FullFileName As String = dir & "\My_File_Name.xlsx"
On a positive note, I pieced together A solution, even though it's not the answer I was looking for....
Dim p() As Process = System.Diagnostics.Process.GetProcessesByName("Excel")
Dim Title As String = p(0).MainWindowTitle
Dim dir As String = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
Dim FullFileName As String = dir & "\" & Replace(Title, "Microsoft Excel - ", "") & ".xlsx"
MsgBox(dir)
MsgBox(Title)
MsgBox(FullFileName)
This will work for now, but I would like to solve it the other way.
Change the line
Dim objWorkBook As Excel.Workbook
to
Dim objWorkBook As Excel.Workbook = Nothing
Also your objWorkBook object is not assigned to anything before you are trying to use it in the line Dim FullName As String = objWorkBook.FullName
Is this what you are trying?
Imports Excel = Microsoft.Office.Interop.Excel
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim objExcel As Excel.Application = System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application")
Dim objWorkBook As Excel.Workbook
Dim totalWorkBooks As Integer = objExcel.Workbooks.Count
MsgBox (totalWorkBooks & " is Number of Open Workbooks")
Dim ActiveBookIndex As Integer = objExcel.ActiveWindow.Index
MsgBox (ActiveBookIndex & " is Active Window Index")
'~~> Set the workbook to say first workbook.
'~~> You can use a loop here as well to loop through
'~~> the workbooks count
objWorkBook = objExcel.Workbooks(1)
Dim FullName As String = objWorkBook.FullName
MsgBox (FullName & " is FullName")
Dim OnlyName As String = objWorkBook.Name
MsgBox (OnlyName & " is Name without the Path")
'
'~~> Rest of the code
'
End Sub
End Class
EDIT: Followup from comments
But let's say I have 9 Workbooks already open, how do I get me app to index, manipulate, switch between them... without knowing the Full Path and File Names ahead of time?
Imports Excel = Microsoft.Office.Interop.Excel
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim objExcel As Excel.Application = System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application")
Dim objWorkBook As Excel.Workbook = Nothing
Dim FullName As String = ""
Dim OnlyName As String = ""
Dim totalWorkBooks As Integer = objExcel.Workbooks.Count
MsgBox (totalWorkBooks & " is Number of Open Workbooks")
For i As Integer = 1 To totalWorkBooks
objWorkBook = objExcel.Workbooks(i)
With objWorkBook
FullName = .FullName
OnlyName = .Name
MessageBox.Show (FullName & " is FullName and " & OnlyName & " is Name without the Path")
'
'~~> Rest of the code here to manipulate the workbook. For example
' objWorkBook.Sheets(1).Range("A1").Value = "Blah Blah"
'
End With
Next i
releaseObject (objExcel)
releaseObject (objWorkBook)
End Sub
'~~> Release the objects
Private Sub releaseObject(ByVal obj As Object)
Try
System.Runtime.InteropServices.Marshal.ReleaseComObject (obj)
obj = Nothing
Catch ex As Exception
obj = Nothing
Finally
GC.Collect()
End Try
End Sub
End Class