So I have all of my VBA code down and it seems to be right, but it just is not refreshing the workbooks. The only thing that I can think of is when I open up the sheets I have to enable editting, so would I need to add something to my code?
Edit: I am running this through a VBScript
Public wb As Workbook
Sub executeUpdate()
`some code
openBook path & testArray(i) & ext, True
saveBookAs path & testArray(i)
End Sub
Sub openBook(ByVal fileName As String, ByVal refresh As Boolean)
Set wb = Workbooks.Open(fileName, 0, False)
If refresh = True Then
wb.RefreshAll
End If
End Sub
Sub saveBookAs(ByVal fName As String)
wb.SaveAs fileName:=fName & "_posReport.xlsx"
End Sub
I found this code over here:
If Application.ProtectedViewWindows.Count > 0 Then
Application.ActiveProtectedViewWindow.Edit
End If
Have not tested it, but maybe it works for you.
--
Quote:
code will bypass the need for the user to select the "Enable Editing" button on the message bar below the ribbon. One additional note [...] the code will error if the workbook isn't in "ProtectedView". So to avoid this the following code will only enable editing if the workbook has "ProtectedView" enabled.
Related
A bit of context, this is my first time programming using VBA in excel,
and I'm trying to create a form that fills out a spreadsheet.
I'm currently getting the error message: "Run-time error '1004': Method 'Worksheets'of object '_Global' failed
I've searched online and have tried various solutions, but I think basically it comes down to a lack of understanding on my part.
Private Sub CommandButton1_Click()
'When pressing save, save values in spreedsheet locations
ActiveSheet.range("c8").Value = ContactName.Value
ActiveSheet.range("b19").Value = ModelNumber.Value
ActiveSheet.range("d19").Value = SerialNumber.Value
ActiveSheet.range("g19").Value = IncidentNumber.Value
ActiveSheet.range("j19").Value = Description.Value
ActiveSheet.range("c7").Value = PortLocation.Value
'save file
ActiveWorkbook.SaveAs Filename:= _
"D:\Users\611281\Downloads\Zebra\EmailMeToZebra.xlsx", FileFormat:=xlOpenXMLWorkbook, ReadOnlyRecommended:=False, CreateBackup:=False
End 'after pressing save, close down sheet.
End Sub
Private Sub UserForm_Initialize()
Me.PortLocation.List = Worksheets("Data lookup_ports").range("e3:e200").Value
Dim MyTempWkBk As Workbook
Dim MyCurrentWin As Window
Set MyCurrentWin = ActiveWindow
Set MyTempWkBk = Workbooks.Open("D:\Users\611281\Downloads\Zebra\GUI.xlsm")
MyCurrentWin.Activate 'Allows only a VERY brief flash of the opened workbook
MyTempWkBk.Windows.Visible = False 'Only necessary if you also need to prevent
'the user from manually accessing the opened
'workbook before it is closed.
'Operate on the new workbook, which is not visible to the user, then close it...
End Sub
Private Sub UserForm_Terminate()
End 'when pressing x, close down window, do not save.
End Sub
I'm getting the error on the code:
Me.PortLocation.List = Worksheets("Data lookup_ports").range("e3:e200").Value
Which is just me trying to populate a ListBox from a spreadsheet range
Have you tried naming the workbook? This is assuming the line with the error is referring to a cell range in thisworkbook. Also, make sure to check the name of the sheet you are referring to for exact spelling (if spelling appears correct, also check for lagging spaces.) Also, is the worksheet hidden? If so, this may need to be added before calling the sheet.
wb.sheets("Data lookup_ports").Visible = True
Can try the below edit in the meantime.
Private Sub UserForm_Initialize()
Dim MyTempWkBk As Workbook
Dim MyCurrentWin As Window
Dim WB as Workbook
Set WB = ThisWorkBook
wb.sheets("Data lookup_ports").Visible = True
Me.PortLocation.List = WB.Sheets("Data lookup_ports").Range("E3:E200").Value
Set MyCurrentWin = ActiveWindow
Set MyTempWkBk = Workbooks.Open("D:\Users\611281\Downloads\Zebra\GUI.xlsm")
MyCurrentWin.Activate
MyTempWkBk.Windows.Visible = False 'Only necessary if you also need to prevent
'the user from manually accessing the opened
'workbook before it is closed.
'Operate on the new workbook, which is not visible to the user, then close it...
End Sub
Private Sub UserForm_Terminate()
End 'when pressing x, close down window, do not save.
End Sub
I have a file that I made with three levels of permissions.
You get prompted to input a password on a userform and you get either admin rights, read/write or only read permissions.
That works fine, unless you don't enable macros.
If you don't enable the macro prompting the userform is not shown and the rights are not set thus you have full access.
I have seen you can use a splash screen but for that to work you need to save the workbook as far as I understand?
The basic concept of them is to beforeclose hide sheets and unhide splash screen, then save the workbook.
But what if the user made a mistake and what to close without save and reopen later? The file gets closed with all sheets visible?
So I thought maybe I can use the "explorer -> right click -> properties -> Read-only" attribute as an extra layer of protection?
I found these functions.
ActiveWorkbook.ChangeFileAccess Mode:=xlreadonly
ActiveWorkbook.ChangeFileAccess Mode:=xlreadwrite
But I tried the readonly line and it did set read only, file could not be saved.
Then I closed the workbook without saving and opened again. But it seems the attribute was not set in the properties of the file since it was not tickmarked and when I opened the file I could save it.
Is there any other way to solve this?
I want to either "force" VBA on the user or make sure he/she can't save the file if it's opened without VBA.
I found a solution that seems to work.
You can in Workbook_BeforeClose use this line to make the file read-only in file properties.
SetAttr Application.ActiveWorkbook.FullName, vbReadonly
This will set the tickmark in the properties and Excel will notice the file is writeprotected.
Then in Workbook_Open() (or as in my case when rights has been established)
SetAttr Application.ActiveWorkbook.FullName, vbReadwrite
ActiveWorkbook.ChangeFileAccess Mode:=xlReadWrite
The first line removes the tickmark in file properties, but Excel still "remembers" the file as read-only.
The second line will tell Excel to make it ReadWrite and the file works as normal again.
This is a far more complicated method than Adreas', but doesn't feature the same risk of mildy tech-savvy users just right-clicking the file and popping into the "Properties" panel.
Create 2 new worksheets. One of them is set to xlVeryHidden - for the examples below, I have called it hsSheetStatus. The other, with a nice large notice telling your hapless minion colleague to enable Macros, will be changing visibility. I have called this hsEnableNotice.
Then I have a Macro to show hsEnableNotice hide all of the other sheets (storing their visibility and the ActiveSheet on hsSheetStatus), and a second Macro to do the reverse (restore visibility/ActiveSheet from hsSheetStatus) and set these to run on Workbook_BeforeSave, Workbook_AfterSave and Workbook_Open:
Option Explicit
Private Sub Workbook_AfterSave(ByVal Success As Boolean)
UnlockAndShow
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
LockAndHide
End Sub
Private Sub Workbook_Open()
UnlockAndShow
End Sub
Private Sub LockAndHide()
Dim lSheet As Long, ActiveName As String
Application.ScreenUpdating = False
Application.EnableEvents = False
ActiveName = ThisWorkbook.ActiveSheet.Name
hsEnableNotice.Visible = xlSheetVisible
hsEnableNotice.Activate
hsSheetStatus.Range(hsSheetStatus.Cells(1, 1), hsSheetStatus.Cells(hsSheetStatus.Rows.Count, 1)).EntireRow.Delete
For lSheet = 1 To ThisWorkbook.Sheets.Count 'By using Sheets instead of Worksheets, we include Charts etc
hsSheetStatus.Cells(lSheet, 1).Value = ThisWorkbook.Sheets(lSheet).Name
hsSheetStatus.Cells(lSheet, 2).Value = ThisWorkbook.Sheets(lSheet).Visible
If ThisWorkbook.Sheets(lSheet).Name = ActiveName Then hsSheetStatus.Cells(lSheet, 3).Value = 1
If ThisWorkbook.Sheets(lSheet).Name <> hsEnableNotice.Name Then ThisWorkbook.Sheets(lSheet).Visible = xlSheetVeryHidden
Next lSheet
ThisWorkbook.Protect Password:="ThisIsMyPassword.ThereAreManyLikeIt,ButThisOneIsMine.", Structure:=True, Windows:=False
Application.EnableEvents = True
End Sub
Private Sub UnlockAndShow()
Dim WasSaved As Boolean, lSheet As Long, lMax As Long
WasSaved = ThisWorkbook.Saved
Application.ScreenUpdating = False
Application.EnableEvents = False
lMax = hsSheetStatus.Cells(hsSheetStatus.Rows.Count, 1).End(xlUp).Row
ThisWorkbook.Unprotect Password:="ThisIsMyPassword.ThereAreManyLikeIt,ButThisOneIsMine."
For lSheet = 1 To lMax
ThisWorkbook.Sheets(hsSheetStatus.Cells(lSheet, 1).Value).Visible = hsSheetStatus.Cells(lSheet, 2).Value
If hsSheetStatus.Cells(lSheet, 3).Value = 1 Then ThisWorkbook.Sheets(hsSheetStatus.Cells(lSheet, 1).Value).Activate
Next lSheet
hsSheetStatus.Visible = xlSheetVeryHidden
hsEnableNotice.Visible = xlSheetVeryHidden
Application.EnableEvents = True
Application.ScreenUpdating = True
ThisWorkbook.Saved = WasSaved
End Sub
I have created a small add-in for my client. It adds 2 buttons to the toolbar and works OK. Now I'd like to add a third button to display the version number and a small help text (15 lines).
I wonder what is the easy way to do this. Options I can think of:
Insert (copy) a sheet with the help & version in the current workbook (efficient and easiest to do, but a bit rude and intrusive)
Create a VBA form with the help text in a label control, and a OK button (very nice, but label content cannot be formatted AFAIK)
write the info to a local HTML file and open that one (perhaps the more versatile?)
Any (other) suggestion ?
Note: I have no admin rights on my pc, so solutions involving additional software are excluded.
Here is the code of the UserForm I created, as per #Arul 's suggestion.
Option Explicit
Private helpFileName As String
Private Sub UserForm_Initialize()
helpFileName = Environ("temp") & "\test.htm"
writeHelpFile
WebBrowser1.Navigate "file:\\" & helpFileName
End Sub
Private Sub writeHelpFile()
Dim fso As Object, Fileout As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set Fileout = fso.CreateTextFile(helpFileName, True, True)
Fileout.Write Sheet4.Range("A1")
Fileout.Close
End Sub
Private Sub UserForm_Terminate()
Kill helpFileName
End Sub
It seems like this guy has had the same problem as me, but the vbModeless doesn't seem to do the trick.
I'm creating a simple add-in, and I want VBA to open a word file, copy the entire content and paste it in the original document.
It works perfectly when executed from the VBA editor or even after the first run where it debugs, but opening a Word instance for the first time and trying to execute the code from the add-in seems to be a problem.
The code is as follows:
Sub insertFigureFrame(control As IRibbonControl)
StandardFrames.StartUpPosition = 0
StandardFrames.Top = Application.Top + (Application.Height - StandardFrames.Height) * 0.5
StandardFrames.Left = Application.Left + (Application.Width - StandardFrames.Width) * 0.5
StandardFrames.Show
End Sub
Sub Standard()
Dim OriginalDocument As String
Dim SaveChanges As Boolean
Dim doc As Document
On Error GoTo err:
Application.DisplayAlerts = wdAlertsNone
Application.ScreenUpdating = False
OriginalDocument = ActiveDocument.Path
Documents.Open MyTemplate
Selection.WholeStory
Selection.Copy
Documents("MyTemplate").Close (SaveChanges = False)
Documents.Open (OriginalDocument)
Selection.PasteAndFormat wdPasteDefault
Exit Sub
err:
Call errHandling
End Sub
The StandardFrames Userform calls the sub Standard.
Any idea what might cause the problem?
EDIT:
I'm using Word 2007 and Windows XP.
Try hidding your userform before you open a document:
Sub Standard()
StandardFrames.Hide
'The rest of your code
End Sub
I created an Add-In that adds a sheet to a Workbook and imports multiple modules. I would then like for the Add-in to run a Subroutine that is now in Active Workbook. This is what I have so far, and I'm getting Run-time error '438': Object doesn't support this property or method.
What is the correct syntax (if it can even be done). Thanks.
' Class name is EventClassModule
Public WithEvents App As Application
Private Sub App_WorkbookOpen(ByVal Wb As Workbook)
If Wb.Name = "Just To Test.xls" Then
Wb.Sheets.Add Type:="C:\TestGLPage.xls"
fname = Dir("C:\Users\Me\Desktop\BAS\*.*", vbNormal)
While fname <> ""
If Right(fname, 3) = "frm" Or Right(fname, 3) = "bas" Or Right(fname, 3) = "cls" Then
ActiveWorkbook.VBProject.VBComponents.Import "C:\Users\Me\Desktop\BAS\" & fname
End If
fname = Dir() 'get the next file
Wend
Call Application.Workbooks("Just To Test.xls").starter
End If
End Sub
VBA is not a dynamic language. When you alter the code or the names of code objects at runtime VBA has to recompile those modules before the changes can be accessed. You may find breakpoints don't work properly after you've made such changes as well.
This recompilation happens automatically and immediately, but is not accessible from code that is already executing. You need to get Excel to re-enter the VBA code.
You may be able to get away with using Application.Run, but I would probably use Application.OnTime to be safer if you don't need starter to be a blocking call (which appears to be the case in your example code).
Just for clarity, when calling a subroutine using Application.Run or Application.OnTime you cannot qualify it using the module name. You can however qualify it using the workbook's name using bang syntax. Eg. Application.Run "Book1.xlsx!SubNameToBeCalled"
Example
I created a blank workbook
I created two modules
Imported
Public Sub RunMe()
MsgBox "Test!"
End Sub
Main
Public Sub Run()
ActiveWorkbook.VBProject.VBComponents.Import "C:\Temp\Imported.bas"
' Showing how to do it with Run
Application.Run ThisWorkbook.Name & "!RunMe"
' Showing the safer way with OnTime
Application.OnTime Now, ThisWorkbook.Name & "!RunMe"
End Sub
I then exported the "Imported" module to "C:\Temp\Imported.bas" and removed it from the project.