I am trying to create a MS Word macro to check and see if a specific powerpoint file is open. If it is then I want it to go to next, but if not then open the file.
Public Sub CommandButton1_Click()
Dim pptApp As Object
Dim pptPres As String
'Dim nSlide As PowerPoint.Presentation
Dim folderPath, file As String
folderPath = ActiveDocument.Path & Application.PathSeparator
file = "Huntington_Template.pptx"
Set pptApp = CreateObject("PowerPoint.Application")
If pptApp.presentations(file).Enabled = True Then
GoTo cont
Else
pptApp.Visible = True
pptApp.presentations.Open (folderPath & file)
End If
cont:
End Sub
A minor variation of Steve's code, in case you want to not just test if the presentation is open, but also use it directly:
Function GetPowerpointFileIfOpen(pptApp As Object, sFullname As String) As Object
For Each p In pptApp.Presentations
If p.FullName = sFullname Then
Set GetPowerpointFileIfOpen = p
Exit Function
End If
Next p
End Function
And then you can test if the presentation is open - or open it otherwise:
Set ppt = GetPowerpointFileIfOpen(pptApp, sFullName)
If ppt Is Nothing Then
Set ppt = pptApp.Presentations.Open(sFullName, False)
End If
Add this to your module (aircode, may need debug help):
Function PPTFileIsOpen(pptApp as object, sFullname as string) as boolean
Dim x as long
For x = 1 to pptApp.Presentations.Count
if pptApp.Presentations(x).fullname = sFullname ) Then
PPTFileIsOpen = True
Exit Function
end if
Next
End Function
Then instead of your:
If pptApp.presentations(file).Enabled = True Then
use:
If Not PPTFileIsOpen(pptApp, folderPath & file) Then
' open the file as you're already doing
End If
I have used this function to determine if a workbook is already open it might work for powerpoint.
Public Function IsWorkBookOpen(FileName As String)
Dim ff As Long, ErrNo As Long
On Error Resume Next
ff = FreeFile()
Open FileName For Input Lock Read As #ff
Close ff
ErrNo = Err
On Error GoTo 0
Select Case ErrNo
Case 0: IsWorkBookOpen = False
Case 70: IsWorkBookOpen = True
Case Else: Error ErrNo
End Select
End Function
You can then call it by doing something like
Ret = IsWorkBookOpen("C:\Book1.xlsm")
If Ret = True Then
Set wb = Application.Workbooks("C:\Book1.xlsm")
wb.Activate
Else
Set wb = Application.Workbooks.Open("C:\Book1.xlsm")
End If
Related
I'm investigating how to automatically update a visio file created with one mastershape (v1.0.vssx) to the next version of the mastershape (v1.1.vssx). When updating each master shape, use Master.Name as the key.
With the code below, I was able to open the vsdx file and vssx and open their respective Masters.
vssx_Master = vssxMaster
vsdx_shape.master = vssx_Master
I wondered if I could update the master shape with the code, but unfortunately vssxMaster is the same as vssxMaster.Name and its type is String.
Is there a way to replace the Master of one shape with another?
not work...
Sub Visio_Update(ByRef VISIOpath As String, ByRef except_sheets() As String, ByRef VSSXpath As String)
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Dim vsoApp As Visio.Application
Dim vsoDoc As Visio.Document
Dim vsoPage As Visio.Page
Dim vsoItemsCnt As Long
Dim vsoShape As Visio.Shape
Dim FileName As String
Dim FileText As String
FileName = Dir(VISIOpath)
FileName = Replace(FileName, ".vsdx", "")
ChDir ThisWorkbook.path
Set vsoApp = CreateObject("Visio.Application")
Call vsoApp.Documents.OpenEx(VISIOpath, visOpenRW)
Set vsoDoc = vsoApp.Documents.Item(1)
vsoItemsCnt = vsoApp.Documents.Count
Call vsoApp.Documents.OpenEx(VSSXpath, visOpenRW)
Set vssxDoc = vsoApp.Documents.Item(vsoItemsCnt + 1)
Set vssxMasters = vssxDoc.Masters
For Each vsoPage In vsoDoc.Pages
For Each vsoShape In vsoPage.Shapes
If Not (vsoShape.Master Is Nothing) Then
On Error Resume Next
mastername = vsoShape.Master.Name
vsoShape.ReplaceShape vssxMasters.Item(vsoShape.Master.Name)
If Err.Number = 0 Then
Debug.Print ("Masters.Item")
Debug.Print "updated succeeded : ", mastername
Err.Clear
Else
Debug.Print ("Masters.Item")
Debug.Print Err.Description
Err.Clear
End If
End If
Next
Next
vsoDoc.SaveAs ThisWorkbook.path & "\data\" & FileName & "_updated_.vsdx"
Application.ScreenUpdating = True
End Sub
Sub test()
choosed_path = "C:\Users\11665307\Desktop\data\vs1.vsdx"
Update_Template = "C:\Users\11665307\Documents\test.vssx"
Call Visio_Update(choosed_path, except_sheets, (Update_Template))
End Sub
I wondered if I could update the master shape with the code
You dont need iterate all masters into stencil :)
For Each vsoPage In doc.Pages
For Each vsoShape In vsoPage.Shapes
If Not (vsoShape.Master Is Nothing) Then
vsoShape.ReplaceShape vssxMasters.Item(vsoShape.Master.Name)
End If
Next
Next
You must iterate through all the shapes on the page. If the shape was created based on the master from stencil v.1.0, then replace it with the corresponding master v.1.1. using the ReplaceShape method
Sub ttt()
Dim sh As Shape
For Each sh In ActivePage.Shapes
If sh.Master.NameU = "Circle" Then sh.ReplaceShape Application.Documents.Item("BLOCK_M.vssx").Masters.ItemU("Diamond")
Next
End Sub
I am using a VBA script where the first worksheets of all workbooks saved in a specific folder are consolidated in one workbook. What I want is, if any source workbook is open while running this script, then I should get a prompt that 'source workbook is open' and the script should not run.
VBA script of destination worksheet is as follows:
Private Sub CommandButton1_Click()
Dim directory As String, fileName As String, sheet As Worksheet, total As Integer
Dim WrdArray() As String
Application.ScreenUpdating = False
Application.DisplayAlerts = False
directory = "C:\test\"
fileName = Dir(directory & "*.xl??")
Application.EnableEvents = False
Do While fileName <> ""
Workbooks.Open (directory & fileName)
WrdArray() = Split(fileName, ".")
For Each sheet In Workbooks(fileName).Worksheets
Workbooks(fileName).ActiveSheet.Name = WrdArray(0)
total = Workbooks("import-sheets.xlsm").Worksheets.Count
Workbooks(fileName).Worksheets(sheet.Name).Copy After:=Workbooks("import-sheets.xlsm").Worksheets(total)
GoTo exitFor:
Next sheet
exitFor:
Workbooks(fileName).Close
fileName = Dir()
Loop
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
I appreciate your help in advance
Untested but it should work, source:
https://support.microsoft.com/en-us/kb/291295
Function IsFileOpen(filename As String)
Dim filenum As Integer, errnum As Integer
On Error Resume Next ' Turn error checking off.
filenum = FreeFile() ' Get a free file number.
' Attempt to open the file and lock it.
Open filename For Input Lock Read As #filenum
Close filenum ' Close the file.
errnum = Err ' Save the error number that occurred.
On Error GoTo 0 ' Turn error checking back on.
' Check to see which error occurred.
Select Case errnum
' No error occurred.
' File is NOT already open by another user.
Case 0
IsFileOpen = False
' Error number for "Permission Denied."
' File is already opened by another user.
Case 70
IsFileOpen = True
' Another error occurred.
Case Else
Error errnum
End Select
End Function
if you want to check if a workbook (an Excel file) is opened, try this function.
Public Function isWbOpened(ByVal wb As String) As Boolean
Dim workB As Workbook
isWbOpened = False
For Each workB In Workbooks
If workB.FullName = wb Or workB.Name = wb Then ''FullName : path + filename Name : filename only
isWbOpened = True
End If
Next workB
End Function
if the function return TRUE, then the Excel file is open, so skeep your script.
example:
if isWbOpened("theExcelFile.xlsx") then
msgbox "theExcelFile.xlsx is open"
end if
You can enumerate the files in a folder then test them to see if any is open before proceeding. Please note - the following code is assuming you are the one with them open, so if a shared file is open this may have to be adapted
Sub TestFolder()
Debug.Print XLFileIsOpen("C:\Test")
End Sub
Function XLFileIsOpen(sFolder As String) As Boolean
For Each Item In EnumerateFiles(sFolder)
If IsWorkBookOpen(CStr(Item)) = True Then XLFileIsOpen = True
Next Item
End Function
Function EnumerateFiles(sFolder As String) As Variant
Dim objFSO As Object: Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim objFolder As Object: Set objFolder = objFSO.GetFolder(sFolder)
Dim objFile As Object, V() As String
For Each objFile In objFolder.Files
If IsArrayAllocated(V) = False Then
ReDim V(0)
Else
ReDim Preserve V(UBound(V) + 1)
End If
V(UBound(V)) = objFile.Name
Next objFile
EnumerateFiles = V
End Function
Function IsArrayAllocated(Arr As Variant) As Boolean
On Error Resume Next
IsArrayAllocated = IsArray(Arr) And Not IsError(LBound(Arr, 1)) And LBound(Arr, 1) <= UBound(Arr, 1)
End Function
Function IsWorkBookOpen(sFile As String) As Boolean
On Error Resume Next
IsWorkBookOpen = Len(Application.Workbooks(sFile).Name) > 0
End Function
I would like to write a macro in outlook to check whether is excel file opening, if this file is not opened, open it and set value for cell(1,1). Else if it is opening, just set value for cell(1,1) no need to open it again. I did it like that and it run okay.
Here is my source code to do like that
Sub test_3()
Dim objExcel As Object
Dim WB As Object
Dim WS As Object
If (IsWorkBookOpen("C:\Users\sang\Desktop\Book2.xlsm") = True) Then 'check whether is file opening? if yes
Set objExcel = GetObject(, "Excel.Application")
objExcel.Visible = True
Set WB = objExcel.Workbooks("Book2.xlsm")
WB.Activate
Else 'file is not opening
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
Set WB = objExcel.Workbooks.Open("C:\Users\sang\Desktop\Book2.xlsm") 'open file
WB.Activate
End If
Set WS = WB.Worksheets("Sheet1")
WS.Range("A1").Value = "haha" 'set value for cell
End Sub
Function IsWorkBookOpen(FileName As String)
Dim ff As Long, ErrNo As Long
On Error Resume Next
ff = FreeFile()
Open FileName For Input Lock Read As #ff
Close ff
ErrNo = Err
On Error GoTo 0
Select Case ErrNo
Case 0: IsWorkBookOpen = False
Case 70: IsWorkBookOpen = True
Case Else: Error ErrNo
End Select
End Function
But my problem is when this file is opening and a few other files are opening,too. It cannot set value for cell and get error "Subscript out of range". When I debug, error locate at "Set WB = objExcel.Workbooks("Book2.xlsm")". Could you please tell me what problem with it, and how can I solve it. Everything just run fine when just have my single excel file, and get problem when have few files are opening with it
You'll run into problems if there are multiple instances of Excel.Application running but this will work otherwise.
Sub TestWrite()
Const FULLNAME As String = "C:\Users\sang\Desktop\Book2.xlsm"
Dim objExcel As Object, WB As Object, WS As Object
Set objExcel = getExcelAppication
objExcel.Visible = True
Set WB = getWorkbook(objExcel, FULLNAME)
If WB Is Nothing Then
MsgBox "File not found: " & FULLNAME, vbInformation, ":("
Else
Set WS = WB.Worksheets("Sheet1")
WS.Range("A1").Value = "haha"
End If
End Sub
Function getExcelAppication() As Object
Dim objExcel As Object
If GetObject("winmgmts:").ExecQuery("select * from win32_process where name='Excel.exe'").Count > 0 Then
Set objExcel = GetObject(, "Excel.Application")
Else
Set objExcel = CreateObject("Excel.Application")
End If
Set getExcelAppication = objExcel
End Function
Function getWorkbook(objExcel As Object, FULLNAME As String) As Object
Dim ShortName As String
Dim WB As Object, WS As Object
ShortName = Right(FULLNAME, Len(FULLNAME) - InStrRev(FULLNAME, "\"))
For Each WB In objExcel.Workbooks
If WB.Name = ShortName Then
Set getWorkbook = WB
Exit Function
End If
Next
Set getWorkbook = objExcel.Workbooks.Open(FULLNAME)
End Function
If there's more than one instance of Excel open, then there's no guarantee that
Set objExcel = GetObject(, "Excel.Application")
will get the instance which has your file open in it.
Try instead
Set objExcel = GetObject("C:\Users\sang\Desktop\Book2.xlsm", "Excel.Application")
or just
Set objExcel = GetObject("C:\Users\sang\Desktop\Book2.xlsm")
The code below will work also on multiple open Excel instances.
Part of the code that was modifed to fit this post, was taken from Ozgrid
The code below is a little long, but other than that it works very nice (tested)
Option Explicit
Private Declare Function FindWindowEx Lib "User32" Alias "FindWindowExA" _
(ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, _
ByVal lpsz2 As String) As Long
Private Declare Function IIDFromString Lib "ole32" _
(ByVal lpsz As Long, ByRef lpiid As GUID) As Long
Private Declare Function AccessibleObjectFromWindow Lib "oleacc" _
(ByVal hWnd As Long, ByVal dwId As Long, ByRef riid As GUID, _
ByRef ppvObject As Object) As Long
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(7) As Byte
End Type
Private Const RETURN_OK As Long = &H0
Private Const IID_IDispatch As String = "{00020400-0000-0000-C000-000000000046}"
Private Const OBJID_NATIVEOM As Long = &HFFFFFFF0
Sub ComplexTest()
Dim hWndXL As Long
Dim oXLApp As Object
Dim oWB As Object
Dim objExcel As Object
Dim WB As Object
Dim WS As Object
Dim FullFileName As String
Dim CleanFileName As String
FullFileName = "C:\Users\sang\Desktop\Book2.xlsm"
CleanFileName = Right(FullFileName, Len(FullFileName) - InStrRev(FullFileName, "\"))
' check if the Excel's file name is already open
If IsWorkBookOpen(FullFileName) Then
' first Excel Window
hWndXL = FindWindowEx(0&, 0&, "XLMAIN", vbNullString)
' got one Excel instance open ?
Do While hWndXL > 0
' Get a reference to current excel instance
If GetReferenceToXLApp(hWndXL, oXLApp) Then
' loop through workbooks
For Each oWB In oXLApp.Workbooks
If oWB.Name = CleanFileName Then
Set WB = oWB
End If
Next
End If
' Find the next Excel Window
hWndXL = FindWindowEx(0, hWndXL, "XLMAIN", vbNullString)
Loop
Else
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
Set WB = objExcel.Workbooks.Open(FullFileName) 'open file
End If
Set WS = WB.Worksheets("Sheet1")
WS.Range("A1").Value = "haha" 'set value for cell
End Sub
' This section of code was taken from Ozgrid
' link: http://www.ozgrid.com/forum/showthread.php?t=182853
'
' The Function Returns a reference to a specific instance of Excel.
' The Instance is defined by the Handle (hWndXL) passed by the calling procedure
Function GetReferenceToXLApp(hWndXL As Long, oXLApp As Object) As Boolean
Dim hWinDesk As Long
Dim hWin7 As Long
Dim obj As Object
Dim iID As GUID
' Rather than explaining, go read
' http://msdn.microsoft.com/en-us/library/windows/desktop/ms687262(v=vs.85).aspx
Call IIDFromString(StrPtr(IID_IDispatch), iID)
' We have the XL App (Class name XLMAIN)
' This window has a child called 'XLDESK' (which I presume to mean 'XL desktop')
' XLDesk is the container for all XL child windows....
hWinDesk = FindWindowEx(hWndXL, 0&, "XLDESK", vbNullString)
' EXCEL7 is the class name for a Workbook window (and probably others, as well)
' This is used to check there is actually a workbook open in this instance.
hWin7 = FindWindowEx(hWinDesk, 0&, "EXCEL7", vbNullString)
' Deep API... read up on it if interested.
' http://msdn.microsoft.com/en-us/library/windows/desktop/dd317978(v=vs.85).aspx
If AccessibleObjectFromWindow(hWin7, OBJID_NATIVEOM, iID, obj) = RETURN_OK Then
Set oXLApp = obj.Application
GetReferenceToXLApp = True
End If
End Function
Function IsWorkBookOpen(FileName As String)
Dim ff As Long, ErrNo As Long
On Error Resume Next
ff = FreeFile()
Open FileName For Input Lock Read As #ff
Close ff
ErrNo = Err
On Error GoTo 0
Select Case ErrNo
Case 0: IsWorkBookOpen = False
Case 70: IsWorkBookOpen = True
Case Else: Error ErrNo
End Select
End Function
I have 2 Excel workbooks. Both are in different folders.
I am copying data from one to another using a macro.
I observe a subscript out of range error...
Any insights in to this ?
Here is my code
Sub copydata()
Dim wkbSource As Workbook
Dim wkbDest As Workbook
Dim shttocopy As Worksheet
Dim wbname As String
' check if the file is open
ret = Isworkbookopen("C:\file1.xlsx")
If ret = False Then
' open file
Set wkbSource = Workbooks.Open("C:\file1.xlsx")
Else
'Just make it active
Workbooks("C:\file1.xlsx").Activate
End If
' check if the file is open
ret = Isworkbookopen("C:\File2.xlsx")
If ret = False Then
' open file
Set wkbDest = Workbooks.Open("C:\file2.xlsx")
Else
'Just make it active
Workbooks("file2.xlsx").Activate
End If
'perform copy
Set shttocopy = wkbSource.Sheets("filedata")
shttocopy.Copy wkbDest.Sheets(3)
End Sub
Function Isworkbookopen(filename As String)
Dim ff As Long, ErrNo As Long
Dim wkb As Workbook
Dim nam As String
wbname = filename
On Error Resume Next
ff = FreeFile()
Open filename For Input Lock Read As #ff
Close ff
ErrNo = Err
On Error GoTo 0
Select Case ErrNo
Case 0: Isworkbookopen = False
Case 70: Isworkbookopen = True
Case Else: Error ErrNo
End Select
End Function
OK, I think I got it. Instead of .Activate, we'll just set the book if it's already open. We'll also reference the book by its file name, NOT path (as I had erroneously suggested in a comment above).
This worked for me:
Sub copydata()
Dim wkbSource As Workbook
Dim wkbDest As Workbook
Dim shttocopy As Worksheet
Dim wbname As String
' check if the file is open
ret = Isworkbookopen("C:\stack\file1.xlsx")
If ret = False Then
' open file
Set wkbSource = Workbooks.Open("C:\stack\file1.xlsx")
Else
'Just make it active
'Workbooks("C:\stack\file1.xlsx").Activate
Set wkbSource = Workbooks("file1.xlsx")
End If
' check if the file is open
ret = Isworkbookopen("C:\stack\File2.xlsx")
If ret = False Then
' open file
Set wkbDest = Workbooks.Open("C:\stack\file2.xlsx")
Else
'Just make it active
'Workbooks("C:\stack\file2.xlsx").Activate
Set wkbDest = Workbooks("file2.xlsx")
End If
'perform copy
Set shttocopy = wkbSource.Sheets("filedata")
shttocopy.Copy wkbDest.Sheets(3)
End Sub
Function Isworkbookopen(filename As String)
Dim ff As Long, ErrNo As Long
Dim wkb As Workbook
Dim nam As String
wbname = filename
On Error Resume Next
ff = FreeFile()
Open filename For Input Lock Read As #ff
Close ff
ErrNo = Err
On Error GoTo 0
Select Case ErrNo
Case 0: Isworkbookopen = False
Case 70: Isworkbookopen = True
Case Else: Error ErrNo
End Select
End Function
Sub CopyData()
Dim Book As Workbook ' probably not needed
Set destinationFile = ThisWorkbook ' probably not needed
sourceFile = ("Add your source file name")
sourceFileLocation = ("add your source file location")
Workbooks.Open (sourceFileLocation + "\" + sourceFile)
Windows(sourceFile).Activate
Range("A1:X7215").Select 'Range Values can be changed depending upon the size of the data (total number of records and columns)
Selection.Copy
destinationFile.Activate
ActiveSheet.Paste
Application.CutCopyMode = False
ActiveWorkbook.Save
Windows(sourceFile).Activate
ActiveWindow.Close
End Sub
Vba newbie. Need a function to output the last modification date of an open workbook. Here is what I have so far but I am getting a message that my formula contains an error when I invoke the function:
Function LastWBModDate(wbname)
ActivateWB (wbname)
LastWBModDate = Format(FileDateTime(ActiveWorkbook.FullName), "m/d/yy h:n ampm")
End Function
Public Function ActivateWB(wbname As String)
If IsWBOpen(wbname) Then
Workbooks(wbname).Activate
Else
MsgBox "Workbook : " & wbname & " is not open " & vbNewLine
End If
End Function
Public Function IsWBOpen(wbname As String) As Boolean
On Error Resume Next
If Workbooks(wbname) Is Nothing Then
IsWBOpen = False
Else
IsWBOpen = True
End If
End Function
Thanks!
Function LastWBModDate(wbname As String)
Dim rv, wb As Workbook
rv = "workbook?" 'default return value
On Error Resume Next
Set wb = Workbooks(wbname)
On Error GoTo 0
If Not wb Is Nothing Then
rv = Format(FileDateTime(wb.FullName), "m/d/yy h:n ampm")
End If
LastWBModDate = rv
End Function
Try below code :
You may also refer this link
Put below code on ThisWorkbook code section
Private Sub Workbook_Open()
LastWBModDate
End Sub
Put this code in any Standard Module
Function LastWBModDate() As String
Dim FSO As Object
Dim File As Object
Set FSO = CreateObject("Scripting.FileSystemObject")
Set File = FSO.GetFile(ThisWorkbook.FullName)
LastWBModDate = Format(File.DateLastModified, "m/d/yy h:n ampm")
Msgbox LastWBModDate
Set FSO = Nothing
End Function