only userform should be visible and not the excel - excel

Please advise as to how can we show only userform and not excel behind it.
I used application.visible = false but it is hiding all the other excel.
I used activatewindow.visible = false but userform is not retrieving the data from excel.
I used activatewindow.displayworkbooktabs=false but it is not hiding the workbook.

Try this code.
Private Sub Workbook_Open()
Application.Visible = False
UserForm1.Show vbModeless
End Sub
Don't forget to make Application visible before close
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Application.Visible = True
End Sub

Write this to userform:
Private Sub CommandButton1_Click()
Dim wCount As Long
Dim i As Long
wCount = Windows.Count
For i = 1 To wCount
Windows(i).Visible = True
Next i
Unload Me
End Sub
Private Sub UserForm_Initialize()
Dim wCount As Long
Dim i As Long
wCount = Windows.Count
For i = wCount To 1 Step -1
Windows(i).Visible = False
Next i
End Sub

Related

ComboBox options based on another ComboBox

below is the code I'm working on to make a UserForm. I'm new to using UserForm and am tryin to populate ComboBox 2 with ComboBox 1 selection. ComboBox 1 holds the name of the worksheets and I'd like ComboBox 2 to update with the column heading names of the selected worksheet. Any help would be greatly appreciated.
Private m_Cancelled As Boolean
Public Property Get Cancelled() As Variant
Cancelled = m_Cancelled
End Property
Private Sub ComboBox1_Change()
'Initialize ComboBox2
Application.EnableEvents = False
ComboBox2.Clear
Application.EnableEvents = True
Debug.Print "Here"; ComboBox1.Value
' Select Case ComboBox1.Value
' Case ComboBox1.Value
With Worksheets(ComboBox1.Value)
Debug.Print "Active Worksheet";
Dim InitialArray() As Variant
Dim i As Integer
Dim ColCount As Integer
' Debug.Print ColCount; RowStart
Do While IsEmpty(Cells(1, ColCount + 1).Value) = False
ColCount = ColCount + 1
' Debug.Print Cells(RowStart, ColCount)
Loop
Debug.Print ColCount; "Cols"
End With
' End Select
' Select Case ComboBox1.Value
For i = 1 To ColCount
Cells(1, i).Add
Next i
' End Select
End Sub
Private Sub ComboBox2_Change()
End Sub
Private Sub CommandButton1_Click()
Hide
End Sub
Private Sub CommandButton2_Click()
' Hide the Userform and set cancelled to true
Hide
m_Cancelled = True
End Sub
Private Sub UserForm_Click()
End Sub
Private Sub UserForm_Initialize()
ComboBox1.Clear
'Initialize ComboBox1
Dim wb As Workbook: Set wb = ThisWorkbook
Dim wCount As Long: wCount = wb.Worksheets.Count
Dim wsNames() As String: ReDim wsNames(1 To wCount)
Dim ws As Worksheet, w As Long
For Each ws In wb.Worksheets
If ws.Visible = xlSheetVisible Then
w = w + 1
wsNames(w) = ws.Name
End If
Next ws
If w < wCount Then ReDim Preserve wsNames(1 To w)
ComboBox1.List = wsNames
' ReDim InitialArray(ActiveWorkbook.Worksheets.Count) As Variant
' Dim i As Integer
'
' ComboBox1.Clear
' For i = 1 To ActiveWorkbook.Worksheets.Count
' InitialArray(i) = ActiveWorkbook.Sheets(i).Name
' Next i
' ComboBox1.List = InitialArray
End Sub
Private Sub UserForm_Activate()
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer _
, CloseMode As Integer)
' Prevent the form being unloaded
If CloseMode = vbFormControlMenu Then Cancel = True
' Hide the Userform and set cancelled to true
Hide
m_Cancelled = True
End Sub
Function GetComboBox1() As String
GetComboBox1 = ComboBox1.Value
End Function

UserForm ComboBox Worksheet Reset

this is the first time I've ever worked with VBA UserForms, I've coded with VBA before and have had some experience producing programs that work in the background but not so much with a user interface. I'd really appreciate some help trouble shooting my dilemma. I took a series of screenshots to represent in order of events what is happening.
This is the number of worksheets before running the UserForm
This is the UserForm with the current worksheets
This is the Updated number of worksheets after closing both the Macro and Userform
This is the Userform with the same number of worksheets
As you can see the number of worksheets did not update after running it a second time and the hidden worksheet is displayed as an option.
Private m_Cancelled As Boolean
Public Property Get Cancelled() As Variant
Cancelled = m_Cancelled
End Property
Private Sub ComboBox1_Change()
End Sub
Private Sub CommandButton1_Click()
Hide
End Sub
Private Sub CommandButton2_Click()
' Hide the Userform and set cancelled to true
Hide
m_Cancelled = True
End Sub
Private Sub UserForm_Click()
End Sub
Private Sub UserForm_Initialize()
ReDim InitialArray(ActiveWorkbook.Worksheets.Count) As Variant
Dim i As Integer
For i = 1 To ActiveWorkbook.Worksheets.Count
InitialArray(i) = ActiveWorkbook.Sheets(i).Name
Next i
ComboBox1.List = InitialArray
End Sub
Private Sub UserForm_Activate()
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer _
, CloseMode As Integer)
' Prevent the form being unloaded
If CloseMode = vbFormControlMenu Then Cancel = True
' Hide the Userform and set cancelled to true
Hide
m_Cancelled = True
End Sub
This is the code I'm currently using. It's a bit rough and tumble because I'm still learning how to use it and it's various properties.
I would like the combobox to update when ran a second time if a worksheet is added or removed.
I'd also like the conbobox to keep the hidden worksheets hidden from the options.
Again any help would be greatly appreciated!
Thank you! :)
Write the Names of Visible Worksheets to a Combo Box
You need an array of visible worksheet names but you don't know how many worksheets are visible. In this case, a better choice is to use a dictionary since its keys (or its items) result in an array.
Private Sub UserForm_Initialize()
With CreateObject("Scripting.Dictionary")
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If ws.Visible = xlSheetVisible Then .Add ws.Name, Empty
Next ws
ComboBox1.List = .Keys
End With
End Sub
If for some reason you want to stick with the array, you could use the following.
Private Sub UserForm_Initialize()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim wCount As Long: wCount = wb.Worksheets.Count
Dim wsNames() As String: ReDim wsNames(1 To wCount)
Dim ws As Worksheet, w As Long
For Each ws In wb.Worksheets
If ws.Visible = xlSheetVisible Then
w = w + 1
wsNames(w) = ws.Name
End If
Next ws
If w < wCount Then ReDim Preserve wsNames(1 To w)
ComboBox1.List = wsNames
End Sub

Allow viewing other sheets while Userform is open within a loop

I made a workbook that has a userform thar is used to fill information in a new row, the information in the textboxes should be prefilled by using the information on the row below. This has to be repeated as many times as an input box value.
So far so good, but now I also need the users to be able to view other sheets in the same workbook where the required information is stored while the userform is open.
if I show the userform modeless I can view other sheets but then the code just keeps going and the second time the userform should pop up it doesn't.
I found a solution to that: using DoEvent.
but now the information is not (pre)filled correctly
Private Sub CommandButton2_Click()
Dim myValue As String
myValue = InputBox("How many do you have?")
If StrPtr(myValue) = 0 Then Exit Sub
For i = 1 To myValue
Range("A4").EntireRow.Insert
UserForm1.Show vbModeless
Do While UserForm1.Visible
DoEvents
Loop
Next
End Sub
What happens now is that the information from a row below is used regardless of any changes made by the user.
Does anyone have a solution?
Edit:
I don't think it is immediately required to understand my question but it might help a bit..
The rest of the code from the userform is as follows
Private Sub CommandButton1_Click()
Unload UserForm1
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
Cancel = True
Range("A4").EntireRow.delete
End
End If
End Sub
Private Sub TextBox1_Change()
Dim myValue As Variant
myValue = TextBox1
Range("A4").Value = myValue
End Sub
Private Sub UserForm_Initialize()
Me.TextBox1.Value = Format(Range("A2"), "dd/mm/yyyy")
Me.TextBox2.Value = Range("B5").Value
Me.TextBox3.Value = Range("C5").Value
Me.TextBox4.Value = Range("D5").Value
Me.TextBox5.Value = Range("E5").Value
Me.TextBox6.Value = Range("F5").Value
Me.TextBox7.Value = Range("G5").Value
Me.TextBox8.Value = Range("H5").Value
Me.TextBox9.Value = Range("J5").Value
Me.TextBox10.Value = Range("K5").Value
End Sub
Private Sub TextBox10_Change()
Dim myValue As Variant
myValue = TextBox10
Range("K4").Value = myValue
End Sub
Private Sub TextBox11_Change()
End Sub
Private Sub TextBox2_Change()
Dim myValue As Variant
myValue = TextBox2
Range("B4").Value = myValue
End Sub
Private Sub TextBox3_Change()
Dim myValue As Variant
myValue = TextBox3
Range("C4").Value = myValue
End Sub
Private Sub TextBox4_Change()
Dim myValue As Variant
myValue = TextBox4
Range("D4").Value = myValue
End Sub
Private Sub TextBox5_Change()
Dim myValue As Variant
myValue = TextBox5
Range("E4").Value = myValue
End Sub
Private Sub TextBox6_Change()
Dim myValue As Variant
myValue = TextBox6
Range("F4").Value = myValue
End Sub
Private Sub TextBox7_Change()
Dim myValue As Variant
myValue = TextBox7
Range("G4").Value = myValue
End Sub
Private Sub TextBox8_Change()
Dim myValue As Variant
myValue = TextBox8
Range("H4").Value = myValue
End Sub
Private Sub TextBox9_Change()
Dim myValue As Variant
myValue = TextBox9
Range("J4").Value = myValue
End Sub
~~
I figured that it indeed had to do with the fact that your initial code did not retrigger the TextBox#_Change subs as intended. I did it a little differently, and triggered them in CommandButton2_Click. This way, you don't need to reload really. But whatever works; just sharing for comparison. So, I am assuming a UserForm like this:
We will move row 4 down on Confirm Input. On Cancel, we'll clear it and exit. And on Confirm Input, the user will (continuously) be asked whether he wants to submit another entry. If not, we'll clear row 4 and exit as well.
So, I've rewritten these parts:
Private Sub CommandButton1_Click()
Range("A4").EntireRow.ClearContents
Unload UserForm1
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
Cancel = True
Range("A4").EntireRow.ClearContents
Range("A4").Resize(1, 11).Interior.Color = vbYellow
End
End If
End Sub
Private Sub CommandButton2_Click()
Range("A4").Resize(1, 11).Interior.Color = vbWhite
Range("A4").Resize(1, 11).Insert
Range("A4").Resize(1, 11).Interior.Color = vbYellow
For i = 1 To 10
myValue = Me.Controls("TextBox" & i).Value
Me.Controls("TextBox" & i).Value = ""
Me.Controls("TextBox" & i).Value = myValue
Next i
answer = MsgBox("Do you wish to add another row?", vbYesNo)
If answer = vbYes Then
Else
Range("A4").EntireRow.ClearContents
Unload UserForm1
End If
End Sub
Private Sub TextBox1_Change()
Dim myValue As Variant
myValue = TextBox1
If myValue = "" Then
Range("A4").Value = myValue
Else
Range("A4").Value = CDate(myValue)
End If
End Sub
You might want to get rid of the color (re)setting bits. But it may be good to realize that the practice of inserting rows all the time may have unintended effects for formatting. Suppose, for whatever reason, you want row 6 to have a red background. As is, the code will keep pushing this formatting one row down each time. This may be what you want, of course... Other than that, the "update" for TextBox1_Change makes sure you export an actual Excel Date, not a string.
Final warning (since we're using vbModeless): be aware that (both in your code and mine) there is no reference to the worksheet. Suppose your user goes into another sheet and clicks Confirm Input there, this will trigger Range("A4").Resize(1, 11).Insert inside the wrong sheet! Seems highly advisable to fix this.
I found a way..
I now changed the sub names of the textbox#_change subs and call them all on "userform unload".
Private Sub CommandButton1_Click() ' this is the command button on the userform
Call TX1
Unload UserForm1
End Sub

Variable not available on UseerForm_Initialize event

I am trying to pass row number to UserForm, so it could display data in user friendly way for end user, but having trouble catching this variable on Initialize moment.
Code in the Worksheet module, it should open UserForm and pass row number as variable:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim DataRange As ListObject
Dim xRow As Long
xRow = Target.Row
Set DataRange = Sheets("Forecast").ListObjects("ForecastTable")
If Application.Intersect(Target, DataRange.DataBodyRange) Is Nothing Or Target.Cells.Count > 1 Then
Exit Sub
Else
MsgBox xRow
With FullInfo
.MyProp = xRow
.Show
End With
End If
End Sub
This is the code in UserForm:
Property Let MyProp(xRow As Long)
publicRow = xRow
End Property
Private Sub UserForm_Initialize()
Dim publicRow As Long
MsgBox publicRow
End Sub
From MsgBox I used for testing I determined that code in the sheet module returns correct row number, but then UserForm is initialized it shows 0 as no data is received. Interestingly enough, I put a button in the user form for testing with following code:
Private Sub Save_Click()
MsgBox publicRow
End Sub
After pressing it - it shows correct row number, so it means it passed but only after Initialize event. How should I pass variable to UserForm so it would be available at Initialize event?
I have a solution for you. :)
...so this is your code corrected ...
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim DataRange As ListObject
Dim xRow As Integer
Dim FullInfo As Object
xRow = Target.Row
Set DataRange = Sheets("Forecast").ListObjects("Tabela1")
If Application.Intersect(Target, DataRange.DataBodyRange) Is Nothing Or
Target.Cells.Count > 1 Then
Exit Sub
Else
Set FullInfo = New UserForm1
With FullInfo
.Label1.Caption = xRow
.Show
End With
End If
End Sub
... if you want to go further, I have another way to pass a public variable to userForm
You code in sheet
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim DataRange2 As ListObject
Dim xRow As Integer
xRow = Target.Row
Set DataRange2 = Sheets("Arkusz1").ListObjects("Tabela2")
If Application.Intersect(Target, DataRange2.DataBodyRange) Is Nothing Or
Target.Cells.Count > 1 Then
Exit Sub
Else
Call UserFormStart(xRow)
End If
End Sub
Put code to new module (in the worksheet do not work)
'Public rowSelection As Integer 'declare public variable
Public Sub UserFormStart(ByVal rowRef As Integer)
rowSelection = rowRef
UserForm1.Show
End Sub
In your userForm
Private Sub CommandButton1_Click()
MsgBox rowSelection & " it's work"
End Sub
Public Sub UserForm_Initialize()
MsgBox rowSelection
End Sub
It works for me :)
You can check one topic
Excel - VBA : pass variable from Sub to Userform

Multiple UserForms that trigger each other; UserForm_QueryClose not working as expected

I've got 5 UserForms and some of them activate depending on what the input of the first UserForm is.
The first UserForm code is below.
Private Sub OptionButton1_Click()
If OptionButton1.Value = True Then
WsName = "CAT"
Unload Me
End If
End Sub
Private Sub OptionButton2_Click()
If OptionButton2.Value = True Then
WsName = "DOG"
Unload Me
End If
End Sub
Private Sub OptionButton3_Click()
If OptionButton3.Value = True Then
WsName = "CATDOG"
Unload Me
End If
End Sub
Private Sub OptionButton4_Click()
If OptionButton4.Value = True Then
WsName = "DOGCAT"
Unload Me
End If
End Sub
Private Sub UserForm_Initialize()
Me.StartUpPosition = 0
Me.Top = Application.Top + 250
Me.Left = Application.Left + Application.Width - Me.Width - 600
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
End
End Sub
When I press the Red "X" to end the entire module that calls the UserForm the module is exited and I am happy. When I press one of the options on the userform like OptionButton1.Value = True then the code also exits the module and I am sad. What am I doing wrong? I would like for the user to be able to press the Red "X" at any point in any UserForm to close out the Module and break out of the code.
The answer to this question was
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If
OptionButton1.Value = False And OptionButton2.Value = False OptionButton3.Value =
False And OptionButton4.Value = False Then
End
End If
End Sub

Resources