VBA - Combo Box scroll down bar broken - excel

I am working on a client management utility for my workplace, with various note entry / viewer system + dropdown for convenience and efficiency.
Right now I am having an issue where on a userform, after clicking a combobox, the user cannot click on the scroll bar to drag down. They can click the arrow to scroll down, but not the bar itself for faster scrolling.
What is weird is that the file I sent, "7.8", was a direct copy of my file but with my colleagues clients info inserted. On my version, made 5 minutes before, the click on scroll down bar works perfectly. I took screenshots of the combo box properties and couldn't find what if anything had changed.
This also occurs on a userform which I made ZERO changes to today, again not working on his but working on mine. Are there common issues that can occur when having multiple workbooks open? All of my userform code targets this workbook & identifties the sheet by codename. All of the other features are working, including much more complex things then whether or not a scroll bar is draggable...
a bit puzzled. Anyone have any ideas?
So I put an example of the code below: I successfully use the same code at several points with small shifts to identify if a given account owner is selected, and if so, load the matching clients, and if a client is selected, to load the timestamp for a note.
What is weird is that the code identified has been the exact opposite of reproducible. I had workbook 7.8, copy-pasted it, changed the client data (which in no way affected the underlying code), and sent to my colleague, whose then experience of the userforms was that the scroll bars can have the button down click but not drag on the bar itself. The only thing I can think of is somehow if having multiple workbooks caused an issue, but out of all of the > 1000 lines of code, there isnt even a single line of code of mine which does anything to the scroll bar. And somehow in the 5 minutes from emailing to him, the scroll bar lost partial functionality?
Sub noteOwnerClients()
Dim wsFound As Worksheet
Dim mainBook As Workbook
Set mainBook = ThisWorkbook
Dim rangeFinder As Range
Dim rangeInt As Integer
Dim rangePull As String
Dim selectedString As String
For Each ws In ThisWorkbook.Worksheets
If StrComp(ws.CodeName, "sheetDatabase", vbTextCompare) = 0 Then
Set wsFound = ws
End If
Next ws
noteClientCombo.Clear
selectedString = noteOwnerCombo.Text
If selectedString <> "" Then
rangeInt = 2
For Each rangeFinder In wsFound.Range("E2:E200")
If selectedString = rangeFinder.Value Then
rangePull = "A" & rangeInt
noteClientCombo.AddItem wsFound.Range(rangePull)
End If
rangeInt = rangeInt + 1
Next
End If
End Sub

Related

Excel | Disable button at start

I am working on an excel file that will work as a calendar with specifications.
I want to have a button at each day. Since I want this to be reusable for other years, I will have buttons on columns with no days (for example, if January starts on a tewsday, Monday will have a button, but nothing on the day, since it is from December).
I know it is possible to set a button enable = False, but I don't know where to put that code. I don't want it to be disabled when another button is clicked but at the opening of the file.
I am new to vba, I'm sorry if this is something really simple.
My approach needs those cells with days from previous month to be empty or "", if theres any value inside it wont work (instead you change the logic to treat cells values like numbers instead of strings).
I noticed that days in your calendar are in string format or so (i.e: "01") that's why I use Len() to evaluate length of string.
This code will set buttons visibility based on TopLeftCell value. Visible = True to days with some value, and Visible = False to empty values.
There is a way to make a button "Enable" but that property is for buttons inside an UserForm.
Tell me if it works for your case, since Sheet.CurrentRegion may cause some issues if your cells are way to much separate from each other, plus it could also hide some other buttons you have. If any of those scenarios do happen let me know, I'll continue helping you anyways!
Sub Set_Buttons_Visibility()
Dim Sheet As Worksheet
Dim Calendar_DataBodyRange As Range
Dim Shape As Shape
'Set Calendar range
Set Sheet = ActiveSheet 'Set Sheet
Set Calendar_DataBodyRange = Sheet.Cells(1, 1).CurrentRegion 'Set current region
Calendar_DataBodyRange.Select '<- comment this after you tested everything[']
'Hide buttons from previous month
For Each Shape In Sheet.Shapes
'If Shape.Visible Then Shape.Select
'Get variables
'Get Button day, as string
strTemp = CStr(Shape.TopLeftCell)
'Get range occupied by button
Set rngTemp = Sheet.Range(Shape.TopLeftCell, Shape.BottomRightCell)
'rngTemp.Select
'Test conditions
'Test rngTemp is part of Calendar_DataBodyRange
bInRange = Not Intersect(Calendar_DataBodyRange, rngTemp) Is Nothing
'Test TopLeftCell has some string
bString = (Len(strTemp) > 0)
'Test bInRange and bShow (True and True)
bCondition = (bString = False) And bInRange
'Perform action
'Set shape visibility
Shape.Visible = Not (bCondition)
'Delete shape (only if you have another procedure to rebuild all buttons)
''''Shape.delete
Next
End Sub
Run code when workbooks opens
To start this function when workbook opens, go to VBA Project Explorer > ThisWorkbook then inside the module you can bind your code to Workbook_Open event. Later on (depending in where you've have stored your code) use the following Run function.
Important:
According to your case you might need to store your code 1) inside the sheet you are working on, in other cases you store your code 2) in a single sheet usually called PERSONAL.XLSB that is always open when Excel itself Opens (Know more about this) so your functions can be accesible for all sheets that you work on.
Pros and Cons:
On the first case is perfect for sharing your work with your boss or colleagues since your code is locally stored in the sheet (but is harder to update, and hard to back up) and the second case is optimal for your own use since all your functions are in the same workbook so you can call it like "[Workbook.Name]![FunctionName],[FunctionParameters]" (allows you to do better updating and an easier backup just by copy-pasting). In any case you can addapt to your necessities.
Private Sub Workbook_Open()
'Run sintax needs Workbook [extension] and string [!]
'Function is stored in current workbook (case 1)
Run ThisWorkbook.Name & "!Set_Buttons_Visibility"
'Function is stored in PERSONAL (case 2)
Run "PERSONAL.XLSB!Set_Buttons_Visibility"
End Sub

How to start macro with a left click NOT on a cell in excel?

I am trying since 2 days to find how to do the following without finding anything that suits the aim:
Steps by order :
user open excel file
he chose between folowing :
Paste an image directly in the worksheet (may be an limited area)
activate some video in the workbook (may be a webcam for start)
he select with a button to activate his clicks detection
he clicks anywhere on the picture and i get the coordinates of clicked points
So far i've seen ppl using (and tested myself) :
mouse event ==> this does not work as i need to know the name of what he is clicking on and it may be a brand new picture he just pasted
BeforeDoubleClick (same, i'd prefer avoid doubleclick but even then it doesnt work when i click on something else but cells)
Selectionchange ==> doesnt work if im not clicking on cells
Place hidden button over the area i want : i cant click a button if its not visible, and it becomes visible when i click it if i put as transparent
If anyone has ideas about this...
(nb: im not a pro of vba so i may have missed something)
Just forgot : my issue is not getting the coordinates of mouse, its just triggering the macro when i want, for now im jsut trying to get a simple msgbox to see if trigger works.
Thanks if anyone has any ideas
BR
Not sure if this fits your need (for example couldn't test it with a video).
a) Place a "button" of any kind on your sheet. I usually use a square shape for that and format it a little bit (color, shade, text). Assign the subroutine SetEvents to it.
b) Declare a global variable that remembers that click-activation is active
Option Explicit
Global EventCatchingActive As Boolean
c) In the event routine of your button, set the OnAction-method for all shapes of the sheet - see the routine setEvents. This ensures that even newly added images handle the click event.
Sub setEvents()
' This routine is called from the magic button.
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(1) ' Set this to whatever sheet you need
Dim button As Shape
Set button = ws.Shapes(Application.Caller)
If EventCatchingActive Then
EventCatchingActive = False
button.TextFrame2.TextRange.Characters.Text = "Start Clicking"
Else
Debug.Print "Setting EventHandler"
Dim sh As Shape
For Each sh In ThisWorkbook.Sheets(1).Shapes
' Debug.Print sh.Name, sh.Type
If sh.Name <> button.Name Then sh.OnAction = "ClickedMe"
Next
EventCatchingActive = True
button.TextFrame2.TextRange.Characters.Text = "Stop Clicking"
End If
End Sub
d) Declare a routine that is called if any of the shapes is clicked. With Application.Caller you can check what was clicked.
Sub ClickedMe(Optional target As Range = Nothing)
If Not EventCatchingActive Then Exit Sub
If target Is Nothing Then
Debug.Print "I clicked on " & Application.Caller
Else
Debug.Print "I clicked on cell " & target.Address
End If
End Sub
(note that code of steps b) to d) goes into a regular module)
e) If you also want to handle clicks on a cell, add the following into the sheet-module of the worksheet you are dealing with.
Private Sub Worksheet_SelectionChange(ByVal target As Range)
ClickedMe target
End Sub

Excel VBA Code won't run "behind" multiple workbook sheets: Better approach?

I am a complete novice, this is my first VBA code (necessity is mother of . . . inept coding by novice).
Problem: Why is my code not updating in real-time? Or in any time at all? Can it be fixed? Do I need to somehow put all 16 sheets worth of VBA code into a "module" or do some other trick to fix it?
Background:
I have VBA code "behind" multiple "client" spreadsheets in a workbook. The code allows cell colors to transfer to a master "all clients" spreadsheet. The reason I needed the VBA code was that there was a function (and INDEX function) already in the color-filled cells.
The code was not working properly, so I figured out that the references were wrong and edited one of the sheets' VBA code to ensure I had the references right. They were correct. But even getting those edited references in that one sheet's code to work correctly took a bunch of clicking around and saving and reopening the document.
I then needed to fix the code in all the other sheets, starting with one of them. I can't for the life of me get anything to happen even though I made the correct edit. I should have seen colors change, but nothing happened.
Google search led me to the news that just putting code "behind" spreadsheets often doesn't work. One reference said I should place it in a module. But I have no idea how to do that across all of my 16 client sheets.
I'm also working over Remote Desktop which is probably not helping. I could probably send myself the workbook if needed.
Below is my code (one sheet's worth). The references are different across sheets so that the various client's data (in vertical columns) populates on the correct horizontal rows of the master sheet. Along with that data are the colors that this VBA code is supposed to help render onto the master sheet.
This is the "Glen" spreadsheet's VBA code, Glen's data that needs to be color coded identically on the "WeeklyRatingsAllClients" sheet (ending up in the BD6:CH6 range and BD7:CH7 range) is in the Q4:Q38 range and the U4:U38 range. The other sheets are the exact same except that in the next person's sheet the BD6:CH6 range and BD7:CH7 ranges will update to become BD8:CH8 range and BD9:CH9 and so on sequentially (next client is 10, 11; next is 12, 13 etc.).
If it matters to anyone, I got the original code here and modified it for my needs: https://www.extendoffice.com/documents/excel/4071-excel-link-cell-color-to-another-cell.html
Also, I make a long comment on above page under "Sara" dated 3 months ago that describes more about the code/purpose and shows how I modified the example code for my purpose and it worked--it's just not working now (probably not useful if you already know this stuff well, like I don't).
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim xRg As Range
Dim xCRg As Range
Dim xStrAddress As String
xStrAddress = "WeeklyRatingsAllClients!$BD$6:$CH$6"
Set xRg = Application.Range(xStrAddress)
Set xCRg = Me.Range("$Q$4:$Q$38")
On Error Resume Next
For xFNum = 1 To xRg.Count
xRg.Item(xFNum).Interior.Color = xCRg.Item(xFNum).Interior.Color
Next
xStrAddress = "WeeklyRatingsAllClients!$BD$7:$CH$7"
Set xRg = Application.Range(xStrAddress)
Set xCRg = Me.Range("$U$4:$U$38")
On Error Resume Next
For xFNum = 1 To xRg.Count
xRg.Item(xFNum).Interior.Color = xCRg.Item(xFNum).Interior.Color
Next
End Sub
Perhaps use the Workbook.SheetSelectionChange event, something like the following. Note that this can definitely be refactored.
Make sure to add this code in the ThisWorkbook module.
Change "Bob", "Fred", "Joe" to the sheet names in question (in order), and add more Cases as needed, always increasing the offsetNum by 2 from the previous Case.
There's a mismatch in the number of cells on the main sheet vs the client sheet. U4:U38 would be 35 cells, but BD6:CH6 is only 31... more an FYI.
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
Dim offsetNum As Long
Select Case Sh.Name
Case "Glen"
offsetNum = 0
Case "Bob"
offsetNum = 2
Case "Fred"
offsetNum = 4
Case "Joe"
offsetNum = 6
Case Else
Exit Sub
End Select
Dim allClientsSheet As Worksheet
Set allClientsSheet = Me.Worksheets("WeeklyRatingsAllClients")
Dim mainColorRange As Range
Set mainColorRange = allClientsSheet.Range("BD6:CH6").offset(offsetNum)
Dim sourceColorRange As Range
Set sourceColorRange = Sh.Range("Q4:Q38")
Dim i As Long
For i = 1 To mainColorRange.Rows(1).Cells.Count
mainColorRange.Rows(1).Cells(i).Interior.Color = sourceColorRange.Cells(i).Interior.Color
Next
Set sourceColorRange = Sh.Range("U4:U38")
For i = 1 To mainColorRange.Rows(2).Cells.Count
mainColorRange.Rows(2).Cells(i).Interior.Color = sourceColorRange.Cells(i).Interior.Color
Next
End Sub

Excel 2010 command button disappears

I'm developing an Excel 2010 workbook, in a manual formulas calculation mode.
(file -> options -> formulas -> Workbook calculation -> manual)
I have some command buttons in the sheet (ActiveX controls), and I set them to move and size with cells (right click on the button -> format control -> Properties -> move and size with text).
This is since I have some rows filtered out under some conditions, and I want the buttons placed in these rows to appear and disappear as well, according to the display mode of their hosting rows.
It all goes perfectly fine, till I save he worksheet when some of the rows (hence buttons) are filtered out (i.e. not displayed).
When I re-open the file again, and expand the filtered rows, the buttons don't show. When checking their properties I see that their visible property is True, but their height is 0, and this doesn't change when I un-filter their hosting rows.
I want to emphasize again that before saving the file - both filtering and un-filtering the buttons worked well.
Would much appreciate any help here.
OK so I get the same results either with ActiveX or Form Controls. For whatever reason, it seems the control's original height does not persist beyond the save & close.
Another option would be to simply clear the AutoFilter on the Workbook's Close and Save events. However, this probably is not what you want if you like to leave some filter(s) on when you save and re-open the file. It's probably possible to save the filter parameters in a hidden sheet or by direct manipulation of the VBE/VBA, but that seems like a LOT more trouble than it's worth. Then you could re-apply the filter(s) when you re-open the workbook.
Here is what code I suggest
NOTE: I relied on the worksheet's _Calculate event with a hidden CountA formula (setting, changing, or clearing the AutoFilter will trigger this event). I put the formula in E1 just so you can see what it looks like:
Since your application relies on Calculation = xlManual then this approach will not work exactly for you but in any case, the subroutine UpdateButtons could be re-used. You would need to tie it in to another event(s) or functions in your application, as needed.
Here is the code
Option Explicit
Private Sub UpdateButtons()
'## Assumes one button/shape in each row
' buttons are named/indexed correctly and
' the first button appears in A2
Dim rng As Range
Dim shp As Shape
Dim i As Long
Application.EnableEvents = False
'## use this to define the range of your filtered table
Set rng = Range("A1:A6")
'## Iterate the cells, I figure maybe do this backwards but not sure
' if that would really make a difference.
For i = rng.Rows.Count To 2 Step -1
Set shp = Nothing
On Error Resume Next
Set shp = Me.Shapes(i - 1)
On Error GoTo 0
If Not shp Is Nothing Then
DisplayButton Me.Shapes(i - 1), Range("A" & i)
End If
Next
Application.EnableEvents = True
End Sub
Private Sub DisplayButton(shp As Shape, r As Range)
'# This subroutine manipulates the shape's size & location
shp.Top = r.Top
shp.TopLeftCell = r.Address
shp.Height = r.Height
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
MsgBox "_Change"
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
''## Assumes one button/shape in each row
'' buttons are named/indexed correctly and
'' the first button appears in A2
'Dim rng As Range
'Dim shp As Shape
'Dim i As Long
'
''## Uncomment this line if you want an annoying message every time
''MsgBox "Refreshing Command Buttons!"
'
'Application.EnableEvents = False
''## use this to define the range of your filtered table
'Set rng = Range("A1:A6")
'
''## Iterate the cells, I figure maybe do this backwards but not sure
'' if that would really make a difference.
'For i = rng.Rows.Count To 2 Step -1
' Set shp = Nothing
' On Error Resume Next
' Set shp = Me.Shapes(i - 1)
' On Error GoTo 0
'
' If Not shp Is Nothing Then
' DisplayButton Me.Shapes(i - 1), Range("A" & i)
' End If
'Next
'
'Application.EnableEvents = True
End Sub
For Another option See this article. You can re-purpose existing commands with RibbonXML customization. While this article is geared towards C# and Visual Studio it's possible to do it with the CustomUI Editor.
I had a similar problem with buttons disapearing (moving on upper left corner) when removing filters.
A solution I found was to add a row above the columns headers so that buttons were still appearing at the top of the columns but were not touching the row where filters were placed.
Adding / removing filters stop interfering with buttons' positions.
I had a similar problem where form buttons appear to work fine, but then disappear after saving and reopening the workbook. Specifically this happened when the form button where part of hidden rows (done using vba code).
Seems like a real bug, although I don't know where the link is.
By changing the form buttons to ActiveX buttons, the buttons stopped disappearing, but started moving/bunching to the top of the screen when the rows were hidden. I just added some vba to re-position the buttons (e.g. CommandButton1.Top = Range(A12:A12).Top --> moves the ActiveX command button to the 12th row).

Launch a different sheet by Spin button

want to use a Spin button (ActiveX Control) to show a previous or next sheet. When the button is clicked the event is successfully triggered and the desired sheet is activated but it holds some elements (commands, graphs, etc.,) from the original sheet and shows these as an appending picture.
Sample code for Down button event :
Private Sub SpinButton_JumpToWeek_SpinDown()
Dim sh_num As String
Dim tmp_num As Integer
Application.ScreenUpdating = False
Application.EnableEvents = False
SpinButton_JumpToWeek.Value = Range("B27").Value - 1
tmp_num = SpinButton_JumpToWeek.Value
' Activate desired KTx sheet
sh_num = "KT" & tmp_num
Range("F27").Value = "" 'reset to blank
Sheets(sh_num).Activate
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
To override this effect I have to manually select (activate) another sheet and then again select the desired sheet. I tried also to automatize this workaround with a macro, but unfortunately it does not work.
It is interesting that this problem do not occur if I execute code in Debug mode (using breakpoint and the stepping line by line).
Surprisingly, I do not have such problem if I try to show the previous/next sheet by writing a value (sheet name index) into a defined cell (i.e. using the Worksheet_Change event). The desired page is correctly shown. See photos.
Sample code for this evententer image description here:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim sh_num As String
Application.ScreenUpdating = False
Application.EnableEvents = False
If Range("F27").Value > 0 Then
' Activate desired KTx sheet
sh_num = "KT" & Range("F27").Value
Range("F27").Value = "" 'reset to blank
Sheets(sh_num).Activate
End If
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
I need to use the Spin button because it is faster and allow me to skip some sheets (for example if these do not have data).
The problem occurs in both 32 and 64-bit Excel.
Do somebody an idea why this problem is occurring and a workaround? Do I have to change some settings or system properties in Excel? Any help would be highly appreciated.
#mehow
I append my commenst here due to large number of words.
I followed your suggestion and tried the example of a UserForm with inserted active control “Microsoft Office Spreadsheet”. I found out that this would not be a good solution for my case, because the response of such sheet is relatively slow (even on a fast PC like mine) when user inserts values into cells. Furthermore, this would greatly complicate my fairly simple *.xlsm workbook, which has more than 50 sheets (1 sheet for each week, the contents of these sheets are then linked to a main sheet), and completely meets my basic necessities (with the exception of this spin button of course).
In my opinion there is probably necessary to manipulate some kind of system property (like for e.g. Application.ScreenUpdating trick), but I do not have enough VBA knowledge to find it.
To clearly explain my question I would need to share my sample workbook, but I do not know how to upload it to this forum. Unfortunately, I am not able upload/show images successfully on this forum (due to my low rating), which would also help a lot.
BTW, I cannot see images on other questions of this forum, too. . Could this problem occur due to missing plugins in a web browser?
You can use a simple trick... before the "Application.screenupdating = true" you can insert the two lines:
ActiveWindow.SmallScroll Down:=-100
ActiveWindow.SmallScroll Up:=100

Resources