make VBA form only read one workbook when other workbooks are open - vba

I'm new here, I've read the rules, but please inform/forgive me if I have missed anything or posted incorrectly.
Now, to my problem:
I have created my first form in Visual Basic that has allowed me to create a searchable and editable database.
Upon allowing colleagues to test the form, I quickly released that they cannot use any of their other Excel workbooks that they have open (The other workbooks are not related in any way to my workbook/form).
After some researching, I found that I can add (vbmodeless) to the button that opens the form. This then allows the team to flick between the form and use other workbooks to look at other information and then go back onto the form.
The only problem I have now, is that when they go back to the form, it reads an error in the macros, because its trying to use the macros on another workbook and not my workbook.
In short, is there any way you can use (vbmodeless), but lock the forms Macros to my specific workbook?
If anyone can solve this riddle, they will be my best friend. I'm aiming to have this ready for its presentation next week on the 6th of March.
Thank you.

Well, let's say like tigeravatar, you haven't declared a workbook :
Dim ws As Workbook
ws = ActiveWorkbook
'instead of
Sheets("Sheet1").Range("A3") = 5 'for example
'you would have
ws.Sheets("Sheet1").Range("A3") = 5
You can also work with the sheets itself, but you'll have to use parameters and search each :
Dim ws As Workbook
Dim sh, SpecificSheet1, SpecificSheet2 as Object 'To manipulate sheets
Dim Name_Sheet1, Name_Sheet2 As String
Set ws = ActiveWorkbook
Name_Sheet1= "Sheet1"
Name_Sheet2= "Sheet2"
For Each sh In Sheets
If InStr(sh.Name, Name_Sheet1) = 1 Then
Set SpecificSheet1 = sh
ElseIf InStr(sh.Name, Nom_Ref_Donnees) = 1 Then
Set SpecificSheet2 = sh
End If
Next
'Instead of :
Sheets("Sheet1").Range("A3") = 5 'for example
'You would use :
SpecificSheet1.Range("A3") = 5
According to your way of using subs, theses both solutions may need to use Public declaration of theses objects :
Option Explicit
Public ws As Workbook
Public SpecificSheet1, SpecificSheet2 as Object 'To manipulate sheets
Sub yoursub()
Dim sh, SpecificSheet1, SpecificSheet2 as Object 'To manipulate sheets
Dim Name_Sheet1, Name_Sheet2 As String
If (IsEmpty(ws)) Then
Set ws = ActiveWorkbook
Else
ws.activate
End If
Name_Sheet1= "Sheet1"
Name_Sheet2= "Sheet2"
For Each sh In Sheets
If InStr(sh.Name, Name_Sheet1) = 1 Then
Set SpecificSheet1 = sh
ElseIf InStr(sh.Name, Nom_Ref_Donnees) = 1 Then
Set SpecificSheet2 = sh
End If
Next
End Sub

Related

VBA Hide all sheets that aren't being used in workbook

I have many sheets in a workbook. I have a main sheet/"form" called "JE" and on that sheet there are buttons and macros that lead to other sheets in the workbook. But, the intention is for other users, not myself, to use the workbook. So, I would only like the sheet that is being used to be visible at any given time. At no time do I want more than 1 sheet to be visible by the user. The user can navigate the workbook mainly thru clicking buttons and certain cells in select sheets that will allow them to navigate throughout the entire workbook. I have tried this by adding code into 'ThisWorkbook' module but it doesn't seem to working as I'd like. When I navigate to one sheet and back to another, some sheets remain visible when I'd like them to be hidden so I'm unsure of what other modifications I can make to code below to get my desired result. If anyone can offer up any modifications or changes I can make to accomplish this, I'd really appreciate it.
UPDATE:
I have added this code to my 'ThisWorkbook' Object:
Option Explicit
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim MySh As Worksheet
For Each MySh In ThisWorkbook.Worksheets
If MySh.Name <> Sh.Name Then MySh.Visible = 0
Next MySh
End Sub
but, when I go to double-click values that usually populate cells in my main sheet ("JE") I get a run-time 1004 error. The values still populate the main sheet but it no longer navigates back to the main sheet as I'd like.
If anyone knows of a solution or a mod I can make, I'd really appreciate it.
The code is nice. Simply put it in the Workbook part of the VBA project:
Option Explicit
Private Sub Workbook_Open()
Dim MySh As Worksheet
For Each MySh In ThisWorkbook.Worksheets
If MySh.Name = ActiveSheet.Name Then MySh.Visible = xlSheetHidden
Next MySh
End Sub
The ThisWorkbook part is here:
In general, I use always something similar, when I am starting an Excel application. I define two Arrays with Visible and Invisible Worksheets and I iterate over them, making them either visible or not visible. Like this:
Option Explicit
Public Sub HideNeeded()
Dim varSheet As Variant
Dim arrVisibleSheets As Variant
Dim arrHiddenSheets As Variant
arrVisibleSheets = Array(Sheet1)
arrHiddenSheets = Array(Sheet2, Sheet3)
For Each varSheet In arrVisibleSheets
varSheet.Visible = xlSheetVisible
Next varSheet
For Each varSheet In arrHiddenSheets
varSheet.Visible = xlSheetVeryHidden
Next varSheet
End Sub
xlSheetVeryHidden makes it possible to unhide it only from the VB Editor. Otherwise you need xlSheetHidden.
It should be Workbook_SheetActivate:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim MySh As Worksheet
For Each MySh In ThisWorkbook.Worksheets
If MySh.Name <> Sh.Name Then MySh.Visible = 0 'zero - false, 1 - true, 2 - very hidden
Next MySh
End Sub
Sub HideInactive()
Set theActiveSheet = ActiveSheet
For Each Sheet In ThisWorkbook.Worksheets
If Sheet.Index <> theActiveSheet.Index Then Sheet.Visible = False
Next
End Sub
I 've test the code. Thank you for reading.

Excel VBA - Copy Workbook into a new Workbook with the macros

So I have a worksheet that generates a chart type of thing using information on 2 other worksheets. On It I have an extract button which should copy the entire workbook into a new workbook whilst making the sheets where the data is pulled from invisible to the user. My issue is, the chart worksheet has other features which require macros to be run, for example buttons that hide some of it etc. The issue is I cannot find whether its actually possible to copy through macros from a workbook into the new copied workbook? Anyone have an answer to this and if so, how would you do this? Here is the code I currently have which copies the workbook into a new workbook:
Sub EWbtn()
Dim OriginalWB As Workbook, NewCRCWB As Workbook
Set OriginalWB = ThisWorkbook
Set NewCRCWB = Workbooks.Add
OriginalWB.Sheets("Generator").Copy Before:=NewCRCWB.Sheets("Sheet1")
OriginalWB.Sheets("Module Part Number Tracker").Copy Before:=NewCRCWB.Sheets("Generator")
OriginalWB.Sheets("CRC").Copy Before:=NewCRCWB.Sheets("Module Part Number Tracker")
Application.DisplayAlerts = False
NewCRCWB.Worksheets("Generator").Visible = False
NewCRCWB.Worksheets("Module Part Number Tracker").Visible = False
NewCRCWB.Worksheets("Sheet1").Delete
Application.DisplayAlerts = True
End Sub
I'd take a copy of the original file and delete/hide sheets from that.
All code is copied over as part of the save.
Sub Test()
Dim wrkBk As Workbook
Dim sCopyFileName As String
Dim wrkSht As Worksheet
sCopyFileName = "C:\MyFolderPaths\Book2.xlsm"
'Create copy of original file and open it.
ThisWorkbook.SaveCopyAs (sCopyFileName)
Set wrkBk = Workbooks.Open(sCopyFileName)
'wrkbk.Worksheets does not include Chart sheets.
'wrkbk.Sheets would take into account all the types of sheet available.
For Each wrkSht In wrkBk.Worksheets
Select Case wrkSht.Name
Case "Generator", "Module Part Number Tracker"
wrkSht.Visible = xlSheetVeryHidden
Case "CRC"
'Do nothing, this sheet is left visible.
Case Else
Application.DisplayAlerts = False
wrkSht.Delete
Application.DisplayAlerts = True
End Select
Next wrkSht
wrkBk.Close SaveChanges:=True
End Sub
I managed to find an answer to my question.. This code works fine however you need to add "Microsoft Visual Basic for Applications Extensibility 5.x" as a reference via Tools -> References. Here is the code:
Dim src As CodeModule, dest As CodeModule
Set src = ThisWorkbook.VBProject.VBComponents("Sheet1").CodeModule
Set dest = Workbooks("Book3").VBProject.VBComponents("ThisWorkbook") _
.CodeModule
dest.DeleteLines 1, dest.CountOfLines
dest.AddFromString src.Lines(1, src.CountOfLines)
Credit: Copy VBA code from a Sheet in one workbook to another?

Excel 2013 random sheet activation post macro run

I am having an issue where by, since updating my Office suite to 2013, the code that I've been running in prior versions worked without issue. However, now in 2013, the (same) macro always activates the last sheet in the book post running. The structure of the book is Control sheet (where buttons and macros are called from), other sheet, ..., final sheet. Upon clicking any of the buttons on the Control sheet, it always results in me being active on the final sheet. This is fully unique to Excel 2013.
Within all of these scrips, there is a protection model (for each sheet in wb.sheets, protect / unprotect) so perhaps in this looping it is somehow glitching at the last sheet?
The syntax for that code is:
Public Sub sbProtection(ByVal sType As String)
Dim wb As Workbook
Dim ws As Worksheet
'Setup
Set wb = ThisWorkbook
'Toggle
If UCase(sType) = "PROTECT" Then
For Each ws In wb.Sheets
ws.Protect sPassword
Next ws
ElseIf UCase(sType) = "UNPROTECT" Then
For Each ws In wb.Sheets
ws.Unprotect sPassword
Next ws
End If
'Cleanup
Set wb = Nothing
Set ws = Nothing
End Sub
Any idea what is happening?

Using VBA to copy a spreadsheet from a secondary workbook into the primary one

I need to take a spreadsheet and compare it with a spreadsheet from another workbook. I know that I can do this using VBA, but I will need to copy a spreadsheet from another workbook so that both spreadsheets will reside within the same workbook and be accessible for comparison. How do I copy a spreadsheet from one workbook into another using VBA?
You don't need to copy the worksheets over to compare them. Simply open both WorkBooks and and set reference to there WorkSheets.
Sub CompareWorkBooks()
Dim wbPending As Workbook
Dim wsPending As Worksheet
Set wbPending = Workbooks("Items Pending")
Set wsPending = wsPending.Worksheet("Items")
Dim wbRecieved As Workbook
Dim wsRecieved As Worksheet
Set wbRecieved = Workbooks("Items Recieved")
Set wsRecieved = Worksheet("Items")
End Sub
If you provide names for Workbooks & WorkSheets and provide column information, we can give you better answers in a shorter period of time. Don't be afraid to post your code either.
If you want a user to select the target workbook and worksheet:
Create a userform
Declare targetWorkbook and tartgetWorksheet at the top of the code module
Add a command button and a combo box
When the button is clicked a file dialog is opened
A reference is now set to the open file
The names of all the worksheets are added to the combo
Changing the combo box value will set the refernce to tartgetWorksheet
Option Explicit
Public targetWorkbook As Workbook
Public tartgetWorksheet As Worksheet
Private Sub CommandButton1_Click()
Dim targetWorkbook As Workbook
Dim ws As Worksheet
Set targetWorkbook = getTargetWorkbook
If targetWorkbook = Nothing Then
MsgBox "Sowmthing went wrong", vbCritical, "Try Again"
Else
For Each ws In targetWorkbook.Worksheets
ComboBox1.AddItem ws.Name
Next
End If
End Function
Function getTargetWorkbook() As Workbook
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
.Show
On Error Resume Next
Set getTargetWorkbook = Application.Workbooks.Open(.SelectedItems(1))
On Error GoTo 0
End With
End Function
Private Sub ComboBox1_Change()
Set tartgetWorksheet = targetWorkbook.Worksheets(ComboBox1.Value)
End Sub

Excel VBA to Work Across Workbooks

I am very new to VBA coding and don't have very good understanding of what I am doing to be honest. But here I go.
I am looking to see if:
Can VBA codes have dyname values? So instead of the code saying execute on a set sheet (e.g "Sheet1") that value changes depending a value in a certain cell.
To trigger a VBA on another workbook. For example I want to run a VBA from Workbook A that triggers a VBA on Workbook B.
To fully explain I want to open Workbook A (and Workbook B if needed, it doesn't matter) and click a button that runs a VBA on Workbook B but on a certain Sheet depending on the value of a cell in Excel A (if the cell says "sheet3" the VBA runs on "sheet3" on Workbook B). I also want cells in Workbook A to reference cells in Workbook B but the the sheet name to by dynamic. For example I have pasted the basic cell reference bellow but instead of having Sheet1 I want it to change depending on the value in a cell.
='[Workbook B.xlsx]Sheet1'!$A$4
I know this sounds very complicates and confusing, but if I could get any help that would be greatly appreciated.
Sub ReportStepOne()
Dim myRow As Long
myRow = 4
Rows(myRow).Value = Rows(myRow).Value
Dim rng As Range
Set rng = Range("A4:AC200")
rng.Cut rng.Offset(1, 0)
Range("A1:AC1").Copy Range("A4:AC4")
End Sub
I want to:
edit this code to make it fire on a certain sheet
make it so the sheet name is referenced to whatever is in cell A o Sheet2 in Report.xlsm.
Run a macro in Report.xlsm that runs the above script (which is called "StepOne" in a file called "Historical Data.xlsm"
The code below takes the value of cell A4 on sheet2 in Reports.xlsm and sets the ws variable to the sheet in Historical data.xlsm which is then used for the rest of the code. If possible I'd advise against having your subs spread out over multiple projects but that is just my opinion. I think it is easier to use proper referencing like below.
Since you want a button trigger on the Report.xlsm I'd suggest moving this code to that workbook. If properly referenced it you can open, edit, save and close any workbook from a single project which again, in my opinion is easier than calling subs in a different project.
Sub ReportStepOne()
Dim wbHis As Workbook, wbRep As Workbook
Dim strWsName As String
Dim ws As Worksheet
Set wbHis = Workbooks("Historical data.xlsm")
Set wbRep = Workbooks("Reports.xlsm")
strWsName = wbRep.Worksheets("Sheet2").Cells(4, 1)
Set ws = wbHis.Worksheets(strWsName)
With ws
With .Rows(4)
.Value = .Value
End With
With .Range("A4:AC200")
.Cut .Offset(1, 0)
End With
.Range("A1:AC1").Copy .Range("A4:AC4")
End With
End Sub
To trigger a VBA on another workbook
Option Explicit
Sub RunVBA()
Dim xlApp As Excel.Application
Dim xlWorkBook As Workbook
Set xlApp = New Excel.Application
Set xlWorkBook = xlApp.Workbooks.Open("C:\Users\Om3r\Desktop\Book1.xlsm")
xlApp.Visible = True
xlWorkBook.Application.Run "Module1.SubName" ' Modulename.Subname
End Sub
To reference worksheet use
Sub CopyRange()
'// From sheet1 to sheet2
Worksheets(2).Range("A1").Value = Worksheets(1).Range("A1").Value
End Sub