Trying to open a excel template and rename or save to new location - vb.net

I get the following error message when I try the following:
Dim XL As New Microsoft.Office.Interop.Excel.Application
XL.Visible = True
XL.Workbooks.Open(XLTemplatePath)
XL.SaveWorkspace(XLSaveReportPath)
XL.Workbooks.Close()
XL.Workbooks.Open(XLSaveReportPath)
"Excel cannot open the file 'ContactReports.xlsx' because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file."
What I would like to do is Open a excel file that is the XLTemplatePath and the either rename or save the file at the XLSaveReportPath and then use that renamed/saved file to fill the report out.
I am using Visual Studio 2008 in VB.NET

The saveworkspace method does not save the file. It save the workspace in the format xlw even though you are naming the file you are saving the workspace in as xls. When you try and open the document you are opening a worspace and you recieve the error.
To have this work correctly you need to get the workbook so you can sabe the workbook instead of the application.
Dim XL As New Microsoft.Office.Interop.Excel.Application
Dim XLWorkbook as new Microsoft.Office.Interop.Excel.Workbook
XL.Visible = True
XLWorkbook = XL.Workbooks.Open(XLTemplatePath)
XLWorkbook.SaveAs(XLSaveReportPath)
XL.Workbooks.Close()
XL.Workbooks.Open(XLSaveReportPath)
Should do the trick. Let us know if you have any problems.
Heare are the MSDN refrences for your review:
Application.SaveWorkspace Method
Workbook.SaveAs Method

I have used the following Visual Basic code to work with Microsoft Excel 2003. The key difference (other than Visual Basic 6 vs VB.Net) is that I use the SaveAs method of the Workbook object rather than the SaveWorkspace method.
Set ExcelApp = CreateObject("Excel.Application")
ExcelApp.Visible = True
Set ExcelDoc = ExcelApp.Workbooks.Open(FileName:=XLTemplatePath, ReadOnly:=True)
ExcelDoc.SaveAs(FileName:=XLSaveReportPath)
ExcelDoc.Close(SaveChanges:=False)
ExcelApp.Workbooks.Open(FileName:=XLSaveReportPath)

Related

Use FileDialog To Select File Then Copy, Paste, Rename, Delete [duplicate]

This question already has answers here:
ms access browse for file and get file name and path
(3 answers)
Closed 2 years ago.
In Access (2016), I am trying to import various Excel files from vendors we use at my work. Their formats are all different, so I need to setup a specific saved import within Access for each one. I then want the users to be able to click the import button, and the excel file be imported to the database.
I initially used the Runsavedimportexport command, but that has a static file path and I don't fully understand transferspreadsheet to be able to use it.
My question is this, how can I use FileDialog to open the file selector, let my users select a file (probably from the desktop), then save that as a variable to run CopyFile. After CopyFile runs and pastes the copy, rename to a specific name, run runsavedimportexport then delete the file.
I have found all the various arguments for each code, but am struggling to tie it all together.
So far all I have managed to put together is
Dim f As Object
Set f = Application.FileDialog(3)
f.AllowMultiSelect = False
f.Show
‘assuming you have added a reference to Microsoft Scripting Library for file system manipulation
‘assuming you have added a reference to Microsoft Office Object 16 library for file dialogs
‘assuming you have used the external data-tab to save some imports from a hidden file named c:\yourdirectory\importme.xlsx
‘assuming you also stored the names of those imports in an access tabled called QueryNames
Then create a form with a listbox and a button. Set the rowsource of the listbox to the QueryNames Table and set the listbox.multiselect to none.
Here is the code:
Private Sub cmdImportData_Click()
Dim fso As FileSystemObject
Dim filedialog As Office.filedialog
Dim filepath As String
dim targetpath as string: targetpath = c:\yourdirectory\importme.xlsx
Set fso = New FileSystemObject
Set filedialog = Application.filedialog(msoFileDialogFilePicker)
filedialog.AllowMultiSelect = False
If filedialog.Show = True Then
filepath = filedialog.SelectedItems(1)
fso.CopyFile filepath, targetpath, True
Dim FirstQueryID As Integer: FirstQueryID = 1 ''crude way to select between 2 stored queries
Dim SecondQueryID As Integer: SecondQueryID = 2
If listboxofQueryNames = FirstQueryID Then
DoCmd.RunSavedImportExport ("MyFirstSavedQuery")
fso.DeleteFile targetpath
End If
Else
DoCmd.RunSavedImportExport ("MySecondSavedQuery")
fso.DeleteFile targetpath
End If
End Sub
Helpful Links
https://learn.microsoft.com/en-us/office/vba/api/access.application.filedialog
Copy and paste a file through access vba

MS Word runs on background and requests documents to be saved even though it is already saved

I have a procedure that creates a PDF file according to an ms word template and its data is retrieved from a database.
It works fine, creates a PDF file perfectly , no run time errors. The problem is that whenever I shut off the computer, ms word prevents the shutdown and if I press cancel ms word shows a message;
The code goes like this;
Dim wordApp As Word.Application
Dim templateBookmarks As Word.Bookmarks
Dim templateName As String
Dim template As Word.Document
'Some other variables for computations
wordApp = CreateObject("Word.Application")
sourceTable = New DataTable
'Some other procs to fill the data table
templateName = "Foo Template.docx"
template = wordApp.Documents.Add(templatePath & templateName)
templateBookmarks = template.Bookmarks
templateBookmarks.Item("sample bookmark").Range.Text = "foo"
'Then fills the table in the template like...
template.Tables(1).Cell(1, 1).Range.Text = dataSource.Rows(0).Item(0)
'Then saves the document as a pdf
Dim saveName As String = "sample file"
template.SaveAs2(savePath & saveName, Word.WdSaveFormat.wdFormatPDF)
I have tried to force garbage collection for the word COM resources, as well as changing the template from an actual document i.e. docx to a word template .dotx. I also tried the method Quit() but it only shows the ms word message much earlier. This is the first time I needed to use interop so pardon if I don't have much idea about it.
The files I needed are saved, the only problem is the ms word message and unsaved and unnecessary files e.g. Document1,Document2,Document3 that seems to be created aside from the required PDF
Use the Document.Close method which closes the specified document after saving files using the PDF file format. It allows specifying the SaveChanges parameter which specifies the save action for the document. Can be one of the following WdSaveOptions constants: wdDoNotSaveChanges, wdPromptToSaveChanges, or wdSaveChanges.
On Error GoTo errorHandler
ActiveDocument.Close SaveChanges:=wdDoNotSaveChanges
errorHandler:
If Err = 4198 Then MsgBox "Document was not closed"

How to Link a VBA code with opened ETABS OAPI?

a project on ETABS 2015 is open on my PC. I want to do some change and process on it by a VBA code automatically. but all the sample code that I found was like this:
Public Sub Example()
Dim SapModel As cSapModel
Dim EtabsObject As cOAPI
Dim FileName as String
Dim ret As Integer = -1
'create ETABS object
EtabsObject = CreateObject("CSI.ETABS.API.ETABSObject")
'start ETABS application
ret = EtabsObject.ApplicationStart()
'create SapModel object
SapModel = EtabsObject.SapModel
'initialize model
ret = SapModel.InitializeNewModel()
'open an existing file - If no file exists, run the Save example first.
FileName = "c:\CSI_API_temp\example.edb"
ret = SapModel.File.OpenFile(FileName)
This code just open a new ETABS in my PC. but my ETABS project is already running and I want to connect to it but I don't know how!
please help me.
Your sample code is basically and typically the one needed to open ETABS ITSELF and to initialize a new model,
ETABSObject = CreateObject("CSI.ETABS.API.ETABSObject") followed by the invocation of ApplicationStart method are the direct means for that.
If you refer to the ETABS API documentation file in the installation destination (e.g "C:\Program Files\Computers and Structures\ETABS 2015\CSi API ETABS 2015.chm" ) Under the section "Release Notes>Attaching to a manually started instance of ETABS", or if you see the same section from the link
http://docs.csiamerica.com/help-files/etabs-api-2015/html/3ceb8889-9028-4de3-9c87-69a12055ade7.htm
you'll find code (in VB.Net) close to what you aim to, but it will not work with vba, so, what you will simply do is this
'The ret variable, just for method invocation convenience
Dim ret As Integer
'Create an instance of the currently opened Program
Dim myETABSObject As ETABS2015.cOAPI
Set myETABSObject = GetObject(, "CSI.ETABS.API.ETABSObject")
'Create an instance to the model
Dim myETABSModel As ETABS2015.cSapModel
Set myETABSModel = myETABSObject.SapModel
'Now, after the "reference instances" are obtained
'Initialize the model (using the model's instance of course)
ret = myETABSModel.InitializeNewModel() 'default units in kip_in_F
'Set the model templete, which is "Blank"
ret = myETABSModel.File.NewBlank()
And You can normally proceed in your coding.
Note: 1- GetObject(CSI.ETABS.API.ETABSObject) method will raise an error if ETABS is not opened.
2- you still can use GetObject even if ETABS is not opened and if you want to open it from windows shell (like using command prompt to open programs instead of double clicking on their respective icons), but this of course needs some Error Handling and the use of "Windows Script Host Object Model".
3- The examples in the documentation (under the documented methods and properties) may not be complete in terms of initiating input data, in cases like this they are just to create an impression of how to use their respective methods and properties.
The code below does as you asked. It uses VBA to connect to a currently running instance of ETABS. Please note if you're running multiple instances of ETABS it may not attach to the one you want.
You'll need to add a reference to 'ETABSv1.tlb' to your VBA project. If you're using VBA Editor for Excel, on the Tools menu select References, then click Browse then add C:\Program Files\Computers and Structures\ETABS 19\ETABSv1.tlb
Sub Main()
'create API helper object
Dim myHelper As ETABSv1.cHelper
Set myHelper = New ETABSv1.Helper
'dimension the ETABS Object as cOAPI type
Dim myETABSObject As ETABSv1.cOAPI
Set myETABSObject = Nothing
'attach to a running instance of ETABS
'get the active ETABS object
Set myETABSObject = myHelper.GetObject("CSI.ETABS.API.ETABSObject")
'get a reference to cSapModel to access all API classes and functions
Dim mySapModel As ETABSv1.cSapModel
Set mySapModel = myETABSObject.SapModel
' DO YOUR WORK BELOW.
MsgBox "Do your work here."
' DO YOUR WORK ABOVE.
'clean up variables
Set mySapModel = Nothing
Set myETABSObject = Nothing
Exit Sub
ErrHandler:
MsgBox "Cannot run API script: " & Err.Description
End Sub
ETABS comes with API documentation that you can find in the installation folder. On my machine it is here: C:\Program Files\Computers and Structures\ETABS 19\CSA API ETABS v1.chm

Do While Loop Code for Excel Declaration

I have very big excel file takes long time to open.
I want to declare xlApp without error as soon as file is ready.
Following code need to be repaired.
Process.Start("C:\Book1.xlsx")
Do While SOMETHING
Application.DoEvents()
Loop
Dim xlApp As Excel.Application = Nothing
xlApp = CType(GetObject(Nothing, "Excel.Application"), Excel.Application)
If I run following line without opening Book1 then following line gives error.
xlApp = CType(GetObject(Nothing, "Excel.Application"), Excel.Application)
Using following code is not good idea because opening time of Book1.xlsx always different.
Threading.Thread.Sleep(10000)
If the file takes long to open, then you just have to wait. But there is something else you can do if that is an option.
Firstly to open the file, use this:
Microsoft.Office.Interop.Excel.Application excel = new Application();
Microsoft.Office.Interop.Excel.Workbook workBook =
excel.Workbooks.Open(fileLocation);
For that you just have to wait but the application is created so it is ready as soon as the file is ready.
If the file takes too long to open, what you can do is convert the file into CSV and save it. Then afterwards, you can read that file whenever you want and you can read it pretty quickly. Again this may not be an option but if it is, then here is how:
workBook.SaveAs(
fileLocation + ".csv",
Microsoft.Office.Interop.Excel.XlFileFormat.xlCSVWindows
);
workBook.Close(true);
excel.Quit();
Then you can read it really fast using File.ReadLines() method. That method will read one line at a time so it will not try to load the whole file but just one line and you can start reading it right away. As you read more lines, it will keep reading them into memory:
foreach (var thisLine in File.ReadLines(fileLocation))
{
// do something
}

Previous Excel instance not getting through IIS

I am using VB.NET to open the Excel files but dont want to create excel object every time.
My code is working perfectly in debug mode, but after publish, it never gets the existing instances and always create new instances which we can see from Task Manager. Here is my code which always returns false in published mode.
My OS is Windows Server 2008. Please guide how to solve this.
Function IsExcelRunning() As Boolean
Dim xlApp As Excel.Application
On Error Resume Next
xlApp = GetObject(, "Excel.Application")
IsExcelRunning = (Err.Number = 0)
MyHelper.writeLog("Excel Instance found=" & IsExcelRunning)
xlApp = Nothing
Err.Clear()
End Function
Here is how I call.
If IsExcelRunning() Then
excelApp = GetObject(, "Excel.Application")
Else
excelApp = Server.CreateObject("Excel.Application")
End If
We used to use Excel Interop and I remember it always being difficult to work with (clunky.) Due to the Interop opening an Excel process and not closing it every time you use it, makes it difficult to work with.
The Interop opens Excel automatically, so all we needed to do was close it. This is what we used to use to kill the Process. Replace YourProcessName with Excel.exe.
Dim proc As System.Diagnostics.Process
Dim info As ManagementObject
Dim search As New ManagementObjectSearcher("SELECT ProcessId FROM Win32_process WHERE caption = 'YourProcessName'")
For Each info In search.Get()
Dim TheString As String = info.GetText(TextFormat.Mof).ToString
proc = System.Diagnostics.Process.GetProcessById(Mid$(TheString, _
(Len(TheString) - 8), 4))
proc.CloseMainWindow()
proc.Refresh()
If proc.HasExited Then GoTo NoKill
proc.Kill()
NoKill:
Next
You'll need to import
Imports System.Management
You'll also need to add the reference 'System.Management' to your project.
See: http://msdn.microsoft.com/en-us/library/vstudio/wkze6zky.aspx for adding a reference to a project.
If you can rather work with CSV, I would suggest you try to. If you are creating the Excel file yourself, try to find a report creator that let's you create / export to Excel. You'll save yourself a lot of time in the long run.