Can I get information from Excel without Microsoft Interop - vb.net

So, I'm very limited with what I can do with vb at work. The edition of vb.net they set me up with doesn't have the files to use the microsoft.office things, and they won't give me permissions to download them. Is there any other way to pull all the information in column E of a spreadsheet?
Thank you for any insight you might be able to give me.

You can use late binding. From the linked page:
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim objApp As Object
Dim objBook As Object
Dim objBooks As Object
Dim objSheets As Object
Dim objSheet As Object
Dim range As Object
' Instantiate Excel and start a new workbook.
objApp = CreateObject("Excel.Application")
objBooks = objApp.Workbooks
objBook = objBooks.Add
objSheets = objBook.Worksheets
objSheet = objSheets.Item(1)
range = objSheet.Range("A1")
'Set the range value.
range.Value = "Hello, World!"
'Return control of Excel to the user.
objApp.Visible = True
objApp.UserControl = True
End Sub

#KenWhite gave the right answer in regards to Excel without Interop, but all you really needed to do was to change the target framework to access the libraries.
You can do this like so. First of all, right click on your project in Solution Explorer and go down to Properties. At this point, you should see a Project properties page, with a Target framework dropdown box, change this from .NET Framework x.x (Client Profile) to .NET Framework x.x.
Now, you can simply select the References tab in the Properties window, click on Add and add Microsoft.Office.Interop.Excel.

Related

copy windowsform chart to clipboard VB

I need to copy a chart (System.Windows.Forms.DataVisualization.Charting.Chart) to clipboard in order to paste it in other application. I use below code but it gives error on the last line for "img" says "Value of Type Bitmap cannot be converted to Bitmapsource"
Any help to rectify the error is highly appreciated.
Private Sub CopyChartBtn_Click(sender As Object, e As RoutedEventArgs) Handles CopyChartBtn.Click
Dim main = DirectCast(Application.Current.MainWindow, MainWindow)
Dim SET_H = DirectCast(main.Frame1.Content, SET_Home)
Dim chart1 = DirectCast(SET_H.Benchchart.Child, System.Windows.Forms.DataVisualization.Charting.Chart)
'save image
Dim img As New System.Drawing.Bitmap(chart1.Width, chart1.Height)
Dim gr As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(img)
chart1.Printing.PrintPaint(gr, New System.Drawing.Rectangle(System.Drawing.Point.Empty, chart1.Size))
Clipboard.SetImage(img)
End Sub
My project is WPF and I am hosting windowsform chart in it. Maybe that is the problem because when I run it in a windows form project it works fine
I used System.Windows.Forms.Clipboard.SetImage(img) and it works.Originally when it is a WPF project it uses System.Windows.Clipboard.SetImage(img) when not using the namespace

Word Interop and getting page count

I know in VBA, within a document, I can get page count using ActiveDocument.Range.Information(wdNumberOfPagesInDocument), But I can't find an equivalent of it in VB.Net using Microsoft.Office.Interop.Word.
Is there, perhaps another way I can attain the quantity of pages in a document?
Public Class Window
'set form level declarations
Dim appPath As String
Dim objWordApp As New Word.Application
Dim objDoc As Word.Document
Dim errorPosition As String
Private Sub Window_Load(ByVal sender As System.Object, e As System.EventArgs) Handles MyBase.Load
objDoc = objWordApp.ActiveDocument
With objDoc
pages = .ActiveDocument.Range.Information(wdNumberOfPagesInDocument)
End With
objDoc = Nothing
End Sub
objWordApp = Nothing
End Class
A way is to get last page number:
lastPageNumber = objDoc.Words.Last.Information[Wd.WdInformation.wdActiveEndPageNumber]
In the Office.Interop.Word Verion 15.0.0
you can try paginate. like this.
objWordApp.Options.Pagination = true;
objWordApp.ActiveDocument.Repagenate();
And Then
DocumentFormat.OpenXml Version 2.12.3
using (WordprocessingDocument document = WordprocessingDocument.Open(filePath, false))
{ document.ExtentedFilePropertuesPart.Properties.Pages.Text }
When you code in VBA, the namespace of the parent application (Word, Excel, etc.) is obvious, so constants such as wdNumberOfPagesInDocument have definitions. With Microsoft.Office.Interop.Word you need to provide the namespace information; for example:
...
With objDoc
pages = .Range.Information(Word.WdInforma‌​tion.wdNumberOfPagesInDocument)
End With
....

Null reference exception when trying to open a workbook, vb.net

I've got an openfiledialog reading a spreadsheet file name from a textbox, then performing some formatting and spitting out a text file. The code works fine one time through; my next task is to get it so that I can open successive spreadsheets (one at a time) without closing the program.
When I try to open a second excel file, I get a null reference exception (object ref not set to an instance of an object) on the line where I'm opening the workbook.
Public Class Form1
Dim xlApp As New Microsoft.Office.Interop.Excel.Application
Dim xlWorkbook, xlWorkbook2 As Microsoft.Office.Interop.Excel.Workbook
Dim xlWsheet, xlWsheet2 As Microsoft.Office.Interop.Excel.Worksheet
Dim strm As System.IO.Stream
Dim FormFile As String = "C:\nitemp.tmp\QuantData.xls"
Private Sub Open_Click(sender As Object, e As EventArgs) Handles Open.Click
'Open button code'
OpenFileDialog1.Title = "Select a File"
OpenFileDialog1.InitialDirectory = directory.Text 'uppermost text box, change to open a different default directory with OPEN button'
OpenFileDialog1.RestoreDirectory = True
OpenFileDialog1.ShowDialog()
End Sub
Private Sub OpenFileDialog1_FileOk(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles OpenFileDialog1.FileOk
Dim lrow As Integer = 0
Try
strm = OpenFileDialog1.OpenFile()
TextBox1.Text = OpenFileDialog1.FileName.ToString()
xlWorkbook = xlApp.Workbooks.Open(TextBox1.Text) 'opens excel file'
xlApp.Visible = False
strm.Close()
I see two possible null references here: 1) the .ToString on the previous line may be empty. WI run the code, the textbox isn't being populated by the correct file path. Only after the error box pops up and I hit 'continue' does the textbox show the correct path.
2) an issue with the platform, 64x vs 32x? This came up in a search, so I tried "New Excel.App" and "New Excel.Workbook", then changed to x86 platform, yet this got me the infamous COM exception 80040154, which makes me think this is not really the issue, but I'm still pretty new to coding..
Can someone find the null?
First things first, you don't need to call OpenFileDialog1.OpenFile(). In fact you don't need to get the filestream at all as you aren't manipulating the file directly (only Excel is).
Secondly, you need to retrieve and dispose of the xlApp.Workbooks collection independently, otherwise you are going to leak some COM wrappers. The null reference exception could be from either the Workbooks collection being null, or the open filename being null. Some error handling will solve your problem.
...
Dim xlWorkbooks as Excel.Workbooks
Dim xlWorkbookOpened as Excel.Workbook
Try
TextBox1.Text = OpenFileDialog1.FileName.ToString()
If (TextBox1.Text IsNot Nothing) Then
xlWorkbooks = xlApp.Workbooks
If (xlWorkbooks IsNot Nothing) Then
xlWorkbookOpened = xlWorkbooks.Open(TextBox1.Text) 'opens excel file'
If (xlWorkbookOpened IsNot Nothing) Then
' DO WHATEVER YOU NEED TO...
Marshal.ReleaseComObject(xlWorkbookOpened)
xlWorkbookOpened = Nothing
End If
Marshal.ReleaseComObject(xlWorkbooks)
xlWorkbooks = Nothing
End If
End If
Catch ex As Exception
' Log error to start with...
Trace.WriteLine(ex.Message)
End Try
Note that I've explicitly released every COM object after use and set the value to Nothing. This is necessary to ensure proper cleanup.

Export data from VB to Excel sheet

On VS 2012 I have created a VB.NET calculation application (outputs based on variable inputs), i need to save these input & output data to certain cells in excel sheet,
here is a sample of the code i use:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim xls As Microsoft.Office.Interop.Excel.Application
Dim xlsWorkBook As Microsoft.Office.Interop.Excel.Workbook
Dim xlsWorkSheet As Microsoft.Office.Interop.Excel.Worksheet
Dim misValue As Object = System.Reflection.Missing.Value
xls = New Microsoft.Office.Interop.Excel.Application
xlsWorkBook = xls.Workbooks.Open("D:\bookl.xlsx")
xlsWorkSheet = xlsWorkBook.Sheets("sheet1")
xlsWorkSheet.Cells(1, 1) = TextBox1.Text
xlsWorkBook.Close()
xls.Quit()
End Sub
my problem here is that in every time i click the save button it saves the data to a excel sheet file which i have to specify its path previously.
What i wish to do is if there is any way to load from VB it self then choose where to save it (because iam going to use it in a lot of machines, so i don't want to put the excel file in the same path each time i use the application in any other machine)
Open Excel file from My.Resources location
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim xlsWorkBook As Microsoft.Office.Interop.Excel.Workbook
Dim xlsWorkSheet As Microsoft.Office.Interop.Excel.Worksheet
Dim xls As New Microsoft.Office.Interop.Excel.Application
Dim resourcesFolder = IO.Path.GetFullPath(Application.StartupPath & "\..\..\Resources\")
Dim fileName = "book1.xlsx"
xlsWorkBook = xls.Workbooks.Open(resourcesFolder & fileName)
xlsWorkSheet = xlsWorkBook.Sheets("Sheet1")
xlsWorkSheet.Cells(1, 1) = TextBox1.Text
xlsWorkBook.Close()
xls.Quit()
MsgBox("file saved to " & resourcesFolder)
End Sub
The resource template xlsx file must be copied to the output directory, so edit its properties and choose (actually I'm not super sure you need this...)
Build Action = Content
Copy To Output Directory = Copy Always
P.S. this is just a sample to use with your current code, but I strongly suggest using EPPlus Library if you want to create/save/modify excel files.

Excel VSTO Workbooks.Open only working when another action is taken first

I am working on a VSTO add-in. I have a customized ribbon, and on that ribbon a button called TemplateCallButton. I also have several other functions and buttons, one of which just opens a folder with templates (included as example). The TemplateCallButton only works and adds in a template file if one of the other actions has been completed (seemingly doesn't matter which one). After any other action has run then it works as expected.
What's more frustrating is that this behavior only seems to happen on machines I deploy on, and not the one I'm developing on. Here is the TemplateCallButton code:
Public Class InsightLabProcessor
Dim MainTemplatePath As String = "C:\Insight\Insight.xltm"
....
Private Sub TemplateCallButton_Click(sender As Object, e As RibbonControlEventArgs) Handles TemplateCallButton.Click
Dim objApp As Excel.Application
objApp = Marshal.GetActiveObject("Excel.Application")
objApp.Visible = True
Dim objWorkbook As Excel.Workbook = objApp.Workbooks.Open(MainTemplatePath)
objWorkbook.Worksheets(4).Activate()
End Sub
and here is the code for the button that just opens a folder:
Private Sub PhaseCodeFolderOpenButton_Click(sender As Object, e As RibbonControlEventArgs) Handles PhaseCodeFolderOpenButton.Click
Process.Start("explorer.exe", "C:\Insight\Phase Codes")
End Sub
or one that opens the control form:
Private Sub ControlPannel_Click(sender As Object, e As RibbonControlEventArgs) Handles ControlPannel.Click
Dim controlpanel As New ControlPanel
controlpanel.Show()
controlpanel = Nothing
End Sub
I feel like I must be missing something simple.
Thanks.
So the problem is in fact the one addressed here: http://support.microsoft.com/kb/238610, which seems pretty vicious to deal with as an add-in. The best solution I've found (again not very elegant) is to just open the command line, write out that we're waiting for the first instance to load, the close it before anyone get's too curious. I tried this on 4 machines and empirically found the longest wait time I needed was 250 ms, so I doubled it to 500 in this:
...
Shell("C:\Windows\System32\cmd.exe", AppWinStyle.MaximizedFocus)
System.Threading.Thread.Sleep(10) 'give cmd just a bit to take the line
SendKeys.Send("Waiting for Excel to register in Running Object Table")
System.Threading.Thread.Sleep(490)
Dim Term() As Process = Process.GetProcessesByName("cmd")
For Each P As Process In Term
P.Kill() 'user probably doesn't have any other instances of cmd open, if they do they are colaterial damage, may handle that if it becomes an issue
Next
Dim objApp As Excel.Application
objApp = Marshal.GetActiveObject("Excel.Application")
objApp.Visible = True
Dim objWorkbook As Excel.Workbook = objApp.Workbooks.Open(MainTemplatePath)
objWorkbook.Worksheets(4).Activate()
Again I would come back and except anything that was more elegant or acceptable to an end user. I would really love to know if there was a way to force Excel to register to the ROT. Perhaps I should turn that into another question.