In my current project, i need to modify an excel file that is already opened. That mean, i need to see the change in the excel file whenever i modify it.
Since opened file is locked and vb cannot access that file, my solution is to open another excel file, modify its content and then copy to the original file using excel vba, as excel vba can be used to copy data between opening sheets.
Here is the vb code in my other excel file (called TTHT.xlsm):
Private Sub Worksheet_CHANGE(ByVal Target As Range)
Application.ScreenUpdating = False
If Sheet1.[B5].Value = "#" Then
Application.DisplayAlerts = False
With Workbooks.Open(ThisWorkbook.Path & "\PCN.xlsm")
With ThisWorkbook.Sheets("TTHT").[B5]
.Parent.Range("B4").Copy
Sheets("PCN").[B4].PasteSpecial 7
End With
End With
Application.DisplayAlerts = True
End If
End Sub
Runs fine between my 2 opening excel file ( that TTHT one and PCN.xlsm ).
Now all I need to do, is to fill the data into TTHT, and put a "#" into B5 by my code. I think it will work, but it's not..
Private Sub btnUpdate_Click(sender As System.Object, e As System.EventArgs) Handles btnUpdate.Click
Dim oExcel As Object
Dim oBook As Object
Dim oSheet As Object
oExcel = CreateObject("Excel.Application")
oExcel.DisplayAlerts = False
oBook = oExcel.Workbooks.Open(TTHTPath)
oSheet = oBook.Worksheets("TTHT")
oSheet.Range("B4").Value = txtValue_Needed.text
oSheet.Range("B5").Value = "#"
oBook.Save()
'System.Diagnostics.Process.Start(DuongDanPhieuCongNghe)
oSheet = Nothing
oBook.Close()
oBook = Nothing
oExcel.Quit()
oExcel = Nothing
End Sub
Result is, if i open the PCN file and click button, it won't change. If I close the PCN and click button, it will change..
But i need to see the change on the fly, not by close and reopen each time i need to update.
Can someone shed me some light, as to how, or which function ... either vba or vb.net, should i use ?
If the file is already opened and has focus then you can try looking it up in the running objects table.
Dim ExcelApplication As Excel.Application
ExcelApplication = GetObject("C:\Folder\ExcelWorkbook.xls")
Then you can just make your modifications on the instance which you referenced while trying to avoid disrupting the user.
The getobject() function is great; here's a link.
https://msdn.microsoft.com/en-us/library/e9waz863(v=vs.71).aspx
Related
I am a beginner in this matter, could you help me, please?
In PowerPoint, I made code linked to a CommandButton that opens a workbook, when I click on it, Excel opens, but it is flashing on the taskbar and the PowerPoint Presentation remains open. It is possible when clicking on the button Excel opens in front of the Presentation?
Private Sub cmbFAUUSP_Click()
Dim ExcApp As Excel.Application
Set ExcApp = New Excel.Application
ExcApp.Visible = True
ExcApp.Workbooks.Open ("C:\Users\Monster PC\Desktop\tabeladedisciplinas FAUUSP.xlsx")
Set pastatrabalho = ExcApp.ActiveWorkbook
pastatrabalho.Application.ActiveWindow.WindowState = xlMaximized
pastatrabalho.Application.DisplayFullScreen = True
End Sub
If you have not, you should declare all your variables. (Use Option Explicit at the top of the module to help you with that, it will warn you if you forgot to declare a variable)
You don't need to set workbook for what you described so I have commented pastatrabalho, uncomment/remove as you need:
Private Sub cmbFAUUSP_Click()
Dim ExcApp As Excel.Application
Dim pastatrabalho As Excel.Workbook 'Uncomment / Remove as needed
On Error Resume Next
Set ExcApp = GetObject(, "Excel.Application") 'This will retrieve the existing instance of Excel if you already have an Excel running
On Error GoTo -1
If ExcApp Is Nothing Then Set ExcApp = New Excel.Application 'Create a new instance of Excel if not
ExcApp.Workbooks.Open ("C:\Users\Monster PC\Desktop\tabeladedisciplinas FAUUSP.xlsx")
'Replace above line with below if you need to refer to the workbook in the later part of your procedure, if any
'Set pastatrabalho = ExcApp.Workbooks.Open ("C:\Users\Monster PC\Desktop\tabeladedisciplinas FAUUSP.xlsx")
With ExcApp
'Setting Left and Top will brings Excel window to the same location as your Powerpoint (applicable if using multiple monitors)
.Left = Application.Left
.Top = Application.Top
.Visible = True
.WindowState = xlMaximized
.DisplayFullScreen = True
.ActiveWindow.Activate
'AppActivate ExcApp.Caption 'another way of activating, must provide the exact same title as the one shown on your Application (which can differ based on version)
End With
End Sub
I have the following vba code. It creates new Excel application and uses it to open a file. Then it MsgBoxes some cell's value in this file.
Sub TestInvis()
Dim ExcelApp As Object
Set ExcelApp = CreateObject("Excel.Application")
Dim WB As Workbook
Set WB = ExcelApp.Application.Workbooks.Open("Y:\vba\test_reserves\test_data\0503317-3_FO_001-2582480.XLS")
Dim title As String
title = WB.Worksheets(1).Cells(5, 4).Value
MsgBox (title)
WB.Save
WB.Close
ExcelApp.Quit
Set ExcelApp = Nothing
End Sub
The problem is that after MsgBoxing it slows down and eventually gives a Microsoft Excel is waiting for another application to complete an OLE action window. Why does it do this? It's not like there are any hard commands being implemented. And how should I deal with it?
This happens because the Excel instance in ExcelApp is waiting for User Input, most likely.
You can try to add ExcelApp.DisplayAlerts = False to skip any pop-ups that might be there.
Also, while troubleshooting add the line ExcelApp.Visible = True so you can see what's going on in the second instance and troubleshoot there.
I encountered this problem in the following situations:
An alert was opened by the Application Instance and it was awaiting user input.
While opening a file, it was coming up with some message about a crash when the file was previously opened and whether I wanted to open the saved version or the in memory version (although this should happen before the msgBox)
If you run the code multiple times and it crashes, it might have the file open as read only since there's another hidden instance of Excel that locked it (check your task manager for other Excel processes)
Rest assured that in any case the problem is not with your code itself - It runs fine here.
Code that works for me.
You can select the file from FileDialog. In comments You have code that close the workbook without saving changes. Hope it helps.
Option Explicit
Sub Import(Control As IRibbonControl)
Dim fPath As Variant
Dim WB As Workbook
Dim CW As Workbook
On Error GoTo ErrorHandl
Set CW = Application.ActiveWorkbook
fPath = Application.GetOpenFilename(FileFilter:="Excel file, *.xl; *.xlsx; *.xlsm; *.xlsb; *.xlam; *.xltx; *.xls; *.xlt ", Title:="Choose file You want to openn")
If fPath = False Then Exit Sub
Application.ScreenUpdating = False
Set WB = Workbooks.Open(FileName:=fPath, UpdateLinks:=0, IgnoreReadOnlyRecommended:=True)
Set WB = ActiveWorkbook
MsgBox("File was opened.")
'Application.DisplayAlerts = False
'WB.Close SaveChanges:=False
'Application.DisplayAlerts = True
'MsgBox ("File was closed")
Exit Sub
ErrorHandl:
MsgBox ("Error occured. It is probable that the file that You want to open is already opened.")
Exit Sub
End Sub
None of these methods worked for me. I was calling a DLL for MATLAB from VBA and a long simulation would pop up that Excel was waiting on another application OLE action, requiring me to click it off for the routine to continue, sometimes quite a few times. Finally this code worked (saved in a new module): https://techisours.com/microsoft-excel-is-waiting-for-another-application-to-complete-an-ole-action/
The way I used it is a little tricky, as the directions don't tell you (here and elsewhere) which causes various VBA errors, so I add to the description for what works in Excel 365:
Create a new module called "ToggleOLEWarning" (or in any new module, important!) which only contains the following code:
Private Declare Function CoRegisterMessageFilter Lib "ole32" (ByVal IFilterIn As Long, ByRef PreviousFilter) As Long
Public Sub KillOLEWaitMsg()
Dim IMsgFilter As Long
CoRegisterMessageFilter 0&, IMsgFilter
End Sub
Public Sub RestoreOLEwaitMsg()
Dim IMsgFilter As Long
CoRegisterMessageFilter IMsgFilter, IMsgFilter
End Sub
Then in your main function, just decorate the long running OLE action with a couple lines:
Call KillOLEWaitMsg
'call your OLE function here'
Call RestoreOLEwaitMsg
And it finally worked. Hope I can save someone the hour or two it took for me to get it working on my project.
Instead of having all the macro's stored in each workbook, we would like to have them stored in one global one. We tried using Personal.xlsb file, however every time excel crashes or system administrator forced restart with excel open it created personal.v.01 ....v.100 files, and they interfered with each other, got corrupted etc.. So instead we are trying to add a small macro to each excel workbook we make which then should open a global excel workbook with all the macros, however it does not open it(normal.xlsb), where is the problem? If I manually run it it works fine, it just does not autorun..
Option Explicit
Public Sub Workbook_Open()
Dim sFullName As String
Dim xlApp As Excel.Application
Dim wbReturn As Workbook
sFullName = "Z:\Dokumentstyring\normal.xlsb"
Set xlApp = GetObject(, "Excel.Application") 'need to do so to open it in same instance otherwise the global macros can not be called.
Set wbReturn = xlApp.Workbooks.Open(filename:=sFullName, ReadOnly:=True)
If wbReturn Is Nothing Then
MsgBox "Failed to open workbook, maybe z drive is down?"
Else
ThisWorkbook.Activate'Dont know how to pass object to modules, so instead activate it and in createbutton set wb= activeworkbook..
Application.Run ("normal.xlsb!CreateButtons")
End If
End Sub
Public Sub Workbook_BeforeClose(Cancel As Boolean)
Dim wb As Workbook
For Each wb In Application.Workbooks
If InStr(UCase(wb.Name), "PARTSLIST") > 0 And wb.Name <> ThisWorkbook.Name Then Exit Sub
Next wb
On Error Resume Next
Workbooks("normal.xlsb").Close
Workbooks("filter.xlsx").Close
End Sub
You create your addin, as just an empty workbook, holding nothing but the code
Like this
Then you add a reference to it, in the workbook that you wish to use, in VBA, like this. My Documents, is a folder on a network drive, not "my documents" local.
And then you can call like so.
So based on input from #Nathan_Sav and #Ralph I have come to a partly good solution:
I have called my addinn Normal and saved this on Z:Dokumenstyring\Normal.xlam
I then removed all the code in Thisworkbook of Normal:
Private Sub Workbook_Open()
Dim ExcelArgs As String
Dim arg As String
ExcelArgs = Environ("ExcelArgs")
'Call deleteMacros.deletePersonalFiles
'MsgBox ExcelArgs
If InStr(UCase(ExcelArgs), "CREO,") > 0 Then
Application.DisplayAlerts = False
If Len(ExcelArgs) > Len("CREO,") Then
arg = Split(ExcelArgs, ",")(1)
Call Creo.addNewPartToPartslist(arg)
End If
Application.DisplayAlerts = True
End If
If InStr(UCase(ExcelArgs), "DOKLIST,") > 0 Then
Application.DisplayAlerts = False
If Len(ExcelArgs) > Len("DOKLIST,") Then
arg = Split(ExcelArgs, ",")(1)
Call ProsjektListen.dbDumpDocOut(arg)
End If
Application.DisplayAlerts = True
End If
and put this in a new workbook called Z:Dokumenstyring\Creo.xlsm
I have so edited all my bat files(which previously were using personal.xlsb):
echo "Launch excel"
Set ExcelArgs=CREO,ADDPART
"C:\Program Files (x86)\Microsoft Office\OFFICE16\Excel.exe" /x /r "z:\Dokumentstyring\Creo.xlsm"
So when I run the bat file it adds a parameter to enviroment, start creo.xlsm, which then starts the addin which launch my userform.
So if I now want to update the look of that that userform I do this by modifying the Z:Dokumenstyring\NormalDebug.xlam, then i save a copy which i write over Z:Dokumenstyring\Normal.xlam and I also told every user to not copy the addin to the default location in excel but keep it in Z:Dokumenstyring\Normal.xlam.
My shapes in my excel sheets seems to work with just the macro name in the procedure, however there might be an conflict if two procedures have the same name, but located in different procedures. So I also altered this to
ws1.Shapes(tempName).OnAction = "Normal.xlam!Custom_Button_Click"
However every click starts a new instance of the addin, how to avoid this?
I am working on a project that requires both an excel document and a word document. I have fully programmed the excel document to work using UserForms, one of which opens automatically when opening the document. (see code below)
Private Sub Workbook_Open()
frmOpen.Show
End Sub
The word document has been programmed to read data from this excel document and write it into a report. (see code below)
Private Sub cmdAutomatic_Click()
Dim objExcel As New Excel.Application
Dim exWb As Excel.Workbook
Dim selectID As String
Set exWb =objExcel.Workbooks.Open("C:\ Path")
exWb.Close
''Data is written into the document here
Set exWb = Nothing
Unload Me
End Sub
The issue is that every time this button is pressed it opens the user form from the excel document and halts the other code until the user form is closed. Is there a way to only have the User Form open when it.
I have tried
Application.EnableEvents = False
However this just returns a method or data member not found (so I assume that this has to be run excel to excel?)
Sorry if this question has already been answered, I could not find anything that addressed this issue. Also sorry if this has a really simple solution, this is for a school project and this is my first time using VBA
Edit:
I realized that doing the following might work
exWb.Application.EnableEvents = False
However because I need to put this before the "Set" for it to stop the form from opening, it doesnt work (as the object is not set at the point the line is run).
You can disable Excel events with objExcel.EnableEvents = False before opening the workbook and reactivate them afterwards with objExcel.EnableEvents = True.
And as #Siddarth Rout told in comments, you can show your UserForm in Modeless mode with frmOpen.Show vbmodeless to avoid blocking other code execution. See MSDN remarks about this : https://msdn.microsoft.com/en-us/library/office/gg251819.aspx
So your code will look like this :
Private Sub cmdAutomatic_Click()
Dim objExcel As New Excel.Application
Dim exWb As Excel.Workbook
Dim selectID As String
objExcel.EnableEvents = False
Set exWb =objExcel.Workbooks.Open("C:\ Path")
exWb.Close
objExcel.EnableEvents = True
''Data is written into the document here
Set exWb = Nothing
Unload Me
End Sub
I am using Excel 2010, and am looking for a VBA script that will open a new workbook in a new window (such that I could, for example, place one workbook on each of 2 monitors).
I'd then place this VBA/macro on the ribbon and assign it a shortcut key. Thus, it'd work like CTRL+N, but the new workbook would open in a separate window/instance of Excel, instead of the same.
I've tried just using Shell ("excel.exe"), but I suppose since it is running from my PERSONAL.XLSB workbook, it then asks if I want to Read Only or Notify.
I just want CTRL+N functionality, but with the new window addition.
Thank you!
You can use this:
Sub NewApp()
With CreateObject("Excel.Application")
.Workbooks.Add
.Visible = True
End With
End Sub
but be aware that any automation of this sort won't load startup workbooks and add-ins by default.
Alternate way to do the same thing, includes selecting the file you want to open:
Sub tgr()
Dim strFilePath As String
Dim xlApp As Object
strFilePath = Application.GetOpenFilename("Excel Files, *.xls*")
If strFilePath = "False" Then Exit Sub 'Pressed cancel
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = True
xlApp.Workbooks.Open strFilePath
End Sub