In the small project I'm currently working on I have multiple Textboxes I control that all have very similar names (seg11, seg21, se31 etc.) that all use the same function. Is it possible to somehow call them all with a for loop?
I think it should look something like this but I'm not sure how I can make the different TextBox names work:
For n As Integer = 0 To 5
i = n
function(seg"n"1)
Next
You can get controls by with use parental control control function whose parameter can be the name of the desired control.
The correct way to string concat, use the & symbol, e.g: "seg" & n & "1"
The correct code for your problem:
For n As Integer = 0 To 5
Dim ctr As Control = Me.Controls("seg" & n & "1")
If ctr IsNot Nothing Then
Debug.WriteLine(ctr.Text)
End If
Next
Related
May seem like a stupid question, but how do you sum variables in VBA to check input data is correct?
I'm trying to check the user has inputted data correctly into a UserForm before they continue to the next page. To do this I want to sum some of their input variables. If they don't input it correctly, they get a message box telling them to revise the numbers. My code is:
Dim BinQnt As Double
Dim FillQnt As Double
Dim FineQnt As Double
Dim CoarQnt As Double
Dim RAPQnt As Double
Dim CRQnt As Double
If BinQnt + FillQnt + FineQnt + CoarQnt + RAPQnt + CRQnt = 100 Then
'Code here for inserting values into database. Omitted to save space and confusion.
Else
MsgBox "Error, please check mixture design sums to 100%."
End If
When I'm testing it, it always goes to the error message box and I'm not sure why. Very sure I am adding variables which sum to 100 (haha). I first tried it without defining the variables, and now I have it still doesn't work.
Am I missing something obvious?
Do you want to round it or not?
In your question, you have the variables as Doubles, and in the answer as integers. Having them as integers will make it easier to hit 100%, but it will round to the nearest integer (2,4 = 2 | 2,6 = 3)
I will assume you are using all texboxes in the form, and as such use this code that is universal:
Dim tot As Double
tot = 0
For Each c In Me.Controls
If TypeName(c) = "TextBox" And IsNumeric(c.Value) Then
tot = tot + c.Value
End If
Next c
If tot = 100 Then
'Code here for inserting values into database. Omitted to save space and confusion.
Else
MsgBox "Error, please check mixture design sums to 100%. Currently at " & tot & "%."
End If
This would give us something like this:
However, using Integer or Long, gives us this:
Also, the reason as to why I'm using IsNumeric(c.Value), is to stop the code from failing in case of empty boxes (or filled with invalid entries).
You could also place a check here in case no boxes are allowed to be empty.
I need to determine if a particular integer does not exists in a datagridview column. I assume I should create an array of the integers from the dgv column, and then compare if the integer exists in the array. However, there is perhaps an easier or simpler way.
I have looked at many articles but none of them resolve my task. Some of the Stack Overflow articles show similar solutions but I can't quite determine what to do.
For a = 0 To Dgv1.RowCount - 1
If Not Dgv1(1, a).Value = Dgv0(1, m).Value Then
Dgv0(1, Dgv0.RowCount - 1).Value = Dgv0(1, m).Value
End If
Next
I hope to compare an integer with a column of integers in a datagridview and if it is present do nothing but if is not present add it to the datagrid view
Are you using wpf? If yes, create a model.
provide a checking mechanism at the setter, use observablecollection or list then bind it to the datagirdview
Get the row and column of the datagridview
then compare (means condtional statement) to the variable you wanna check
and of course it should be inside of loop, loop count is equal to the count of rows you have in the datagridview.
Here's an example code:
Dim column As String = "YourColumnNameHere"
' Assuming 2 is the number you wanna compare
Dim value As Integer = 2
For row As integer = 0 to dataGridView.RowCount - 1
If dataGridView.Rows(row).Cells(column).Value = value Then
' Do something here
Else
' Do something here
End If
Next
Currently, I am displaying an XtraGrid that contains Group Rows. I have a "Select All" DevExpress.XtraEditors.CheckEdit control (which is different from this elusive "Select All" check box control I am reading about in the documentation). It is different for a reason: I want the check box to do something other than "Select All" (which comes in only three different varieties according to the DevExpress Docs.).
I want a user to be able to do one of two things with the CheckEdit control. [1] If no Group Rows are expanded, I want to select all Group Rows. [2] If one or more Group Rows are expanded, I only want to select the expanded rows.
Presently, I am able to manipulate the controls to do only one of the two things (see code). My question is twofold: is this possible; and, if so, how would I go about it?
Here is my code that does the second of the two 'things' described above:
'If the CheckEdit control is checked:
xtraGrid.SelectAll()
Dim rowHandles() As Int32 = xtraGrid.GetSelectedRows()
If rowHandles.Count > 0 Then
For Each RowHandle As Int32 In rowHandles
If xtraGrid.IsGroupRow(RowHandle) Then
xtraGrid.UnselectRow(RowHandle)
End If
Next
End If
As you can see, all this really is just a work around. There is also presumably more overhead than needed in my calling .GetSelectedRows(). I am just attempting to sort through the row types in order to keep the row selected or .UnselectRow()
You can use GridView.GetRowExpanded method to check whether a specific group row is expanded. For iterating through visible rows you can use GridView.RowCount property. To get row level just use GridView.GetRowLevel method. Also you need to check wether a row is new item row or is filter row by using GridView.IsNewItemRow method and GridView.IsFilterRow method. For all of this methods you need to get Row handle by using GridView.GetVisibleRowHandle method. When you are working with selection is better to use GridView.BeginSelection method and GridView.EndSelection method outside of your code.
UPDATE: If you want to select hidden rows within a collapsed group then you can use GridView.GetChildRowCount method and GridView.GetChildRowHandle method to get all hidden rows.
Here is some sample code that is performing your two things together:
Private Sub SomeSub
If xtraGrid.GroupCount = 0 Then
xtraGrid.SelectAll()
Exit Sub
End If
xtraGrid.BeginSelection()
xtraGrid.ClearSelection()
Dim isExpanded As Boolean = False
For rowVisibleIndex = 0 To xtraGrid.RowCount - 1
Dim rowHandle As Integer = xtraGrid.GetVisibleRowHandle(rowVisibleIndex)
If xtraGrid.IsNewItemRow(rowHandle) Then
Continue For
End If
Dim level As Integer = xtraGrid.GetRowLevel(rowHandle)
If level = 0 Then
If Not isExpanded Then
isExpanded = xtraGrid.GetRowExpanded(rowHandle)
If isExpanded Then
xtraGrid.ClearSelection()
Else
xtraGrid.SelectRow(rowHandle)
End If
End If
Else
xtraGrid.SelectRow(rowHandle)
'Update: select hidden rows
If xtraGrid.IsGroupRow(rowHandle) And Not xtraGrid.GetRowExpanded(rowHandle) Then
SelectRowHierarchy(rowHandle)
End If
End If
Next
xtraGrid.EndSelection()
End Sub
Private Sub SelectRowHierarchy(rowHandle As Integer)
Dim childCount As Integer = xtraGrid.GetChildRowCount(rowHandle)
For childIndex As Integer = 0 To childCount - 1
Dim childRowHandle As Integer = xtraGrid.GetChildRowHandle(rowHandle, childIndex)
xtraGrid.SelectRow(childRowHandle)
If xtraGrid.IsGroupRow(childRowHandle) Then
SelectRowHierarchy(childRowHandle)
End If
Next
End Sub
I want to loop select all slicer items within a certain range . Let's say , all items from 3 to 6 . My slicer contains the following items 1 , 2, 3, 5, 6, 8
Here is what I tried
Sub SlicerTest()
With ActiveWorkbook.SlicerCaches("Slicer_rtytr")
Dim maxNumberOfDays As Long
maxNumberOfDays = 9 'I want to be able to identify the number of items programmatically but do not know how to do this
Dim fromDay As Long
fromDay = 3
Dim toDay As Long
toDay = 6
For i = 1 To maxNumberOfDays
If (i > fromDay And i < toDay) Then
.SlicerItems(CStr(i)).Selected = True
Else
.SlicerItems(CStr(i)).Selected = False
End If
Next i
End With
End Sub
The result should be that the slicer picks only 5 but it throws an error . I tried a regular 1,2,3,4,5,6,7,8 array and it works fine . I guess this one does not work because of missed values ?
This article explains what you need, and some.
https://paultebraak.wordpress.com/2012/02/24/accessing-the-slicer-through-vba/
The relevant bit:
Dim sC As SlicerCache
Dim SL As SlicerCacheLevel
Dim sI As SlicerItem
Set sC = ActiveWorkbook.SlicerCaches(“Slicer_Dates_Hie”)
Set SL = sC.SlicerCacheLevels(1)
Debug.Print “——————————————————————————“
For Each sI In SL.SlicerItems
Debug.Print “Caption –> ” & sI.Caption
Debug.Print “Value –> ” + CStr(sI.Value)
Debug.Print “Unique Name –> ” + sI.Name
Debug.Print “——————————————————————————“
Next
The reason that a normal array works (normal being quantified as containing 9 elements in an array in this context) is because you specify that you want to loop from 1 to 9 in this line here For i = 1 To maxNumberOfDays. In your example you only have 6 items so you'll hit an error by trying to access more items than are currently within the array.
I'm not too familiar with slicer objects unfortunately, but, to fix this issue you'll want to know exactly how many items are within your slicer. After a quick look at the documentation on silcers there doesn't appear to be a count property, however, there is a numberOfColumns property. If the column number correlates with how many objects you have (again not entirely sure that it does) then just assign:
maxNumberOfDays = ActiveWorkbook.SlicerCaches("Slicer_rtytr").numberOfColumns
If this does not work I would explore other options for figuring out the number of elements that will be within your array.
I've been messing around with VBA in Excel a bit recently; and as a small project for myself, I'm trying to create a "draw names from a hat" sort of macro.
I began by generating a random number, and then choosing which entry from a Table (i.e. ListObject) would be selected using a case statement. The problem with this is that it only works of the number of Table entries is always the same.
So my question (probably a ridiculous one) is: is it possible at all to generate a dynamic 'Select Case' block, where the number of cases on the block is based on the number of entries in the Table?
Thanks.
-Sean
Edit: To clarify: what I am trying to do, exactly, is this:
I generate a random number, i, from 1 to n=10*(number of Table entries). After this, I want to display, in a cell, one of the table entries based on the random number.
Ideally, the code would work similarly to this:
if i = 1 to 10 then choose event 1
if i = 11 to 20 then choose event 2
if i = 21 to 30 then choose event 3
...
if i = (n-9) to n then choose event (n/10)
I hope this helps to clarify the goal of the code.
From our comments here is something you can use:
Sub random()
Dim used_rows As Integer
Dim random As Integer
Dim cell_array() As Integer
used_rows = Sheet1.UsedRange.Rows.Count
ReDim cell_array(used_rows)
For i = 1 To used_rows
cell_array(i - 1) = Cells(i, 1)
Next
random = Int(Rnd * (used_rows))
MsgBox cell_array(random)
End Sub
You can go ahead and change MsgBox to whatever you like, or set like Cell(1,4).Value = cell_array(random), or however you'd like to proceed. It will be based off the number of rows used. Though depending on how you implement your spreadsheet the code might have to be changed a bit.
Here's the update code from the suggestions from the comments. Also remember to use Randomize() in your form initialization or WorkBook Open functions.
Sub random()
Dim used_rows As Integer
Dim random As Integer
'Multiple ways to get the row count, this is just a simple one which will work for most implementations
used_rows = Sheet1.UsedRange.Rows.Count
random = Int(Rnd * (used_rows))
'I use the variable only for the reason that you might want to reference it later
MsgBox Cells(random, 1)
End Sub
This assumes that by "table" you mean "Table with a capital T", known in VBA as a ListObject:
Sub PickRandomTens()
Dim lo As Excel.ListObject
Dim ListRowsCount As Long
Dim RandomNumber As Long
Dim ListEvent As String
Dim Tens As Long
Set lo = ActiveSheet.ListObjects(1)
ListRowsCount = lo.DataBodyRange.Rows.Count
RandomNumber = Application.WorksheetFunction.RandBetween(10, ListRowsCount * 10)
ListEvent = lo.ListColumns("Data Column").DataBodyRange.Cells(Int(RandomNumber / 10))
MsgBox "Random number: " & RandomNumber & vbCrLf & _
"Event: " & ListEvent
End Sub