Select Second Pivot Table Row Data After First Row Input VBA Userforms & ComboBox - vba

I have a Userform in which I submit some data, from the data my box populates with more data, and after I select the data from that box I need to select data from for that item from a third box. The data gathered is from a PivotTable.
Box1 is just a supplied combobox while 2 and 3 are directly from a PivotTable. I have the functionality for Box2 working based off Box1 but that's because they are separated by sheets.
The goal is that Box1 can = A,B,C then if Box1=A then Box2 can = 1,2,3 then if Box2 = 1 then Box3= x,y,z.
The problem being in Box3 it returns the information for Box2= 1,2 AND 3 rather than just 1.
My current code is:
lCommentCount = Sheets(pt).PivotTables("Pivottable1").TableRange2.Rows.Count
For i = 1 To lCommentCount
If Me.ptDatabox.Value = Sheets(pt).PivotTables("PivotTable1").PivotFields("ptData").LabelRange.Offset(i, 0).List Then
OEEDataEntry.commentbox.AddItem Sheets(pt).PivotTables("PivotTable1").PivotFields("ptData").LabelRange.Offset(i, 1)
End If
Next i
For i = Me.commentbox.ListCount - 1 To 0 Step -1
If Me.commentbox.List(i) = "" Or Me.commentbox.List(i) = "Grand Total" Or Me.commentbox.List(i) = ("(blank)") Then
Me.commentbox.RemoveItem (i)
End If
Next i

I have been toying around with this all day and found that you have to make the second row visible. This code works well. Note showing the detail BEFORE counting.
Sheets(pt).PivotTables("PivotTable1").PivotFields("ptData").ShowDetail = _
True
For i = 1 To lCommentCount
pti = Sheets(pt).PivotTables("PivotTable1").PivotFields("ptData").LabelRange.Offset(i, 0).Value
If Me.ptDatabox.Text = pti Then
OEEDataEntry.commentbox.AddItem Sheets(pt).PivotTables("PivotTable1").PivotFields("ptData").LabelRange.Offset(i, 1)
End If
Next i
For i = Me.commentbox.ListCount - 1 To 0 Step -1
If Me.commentbox.List(i) = "" Or Me.commentbox.List(i) = "Grand Total" Or Me.commentbox.List(i) = ("(blank)") Then
Me.commentbox.RemoveItem (i)
End If
Next i
If for whatever reason you want to change the information given in the first box then you would need to make it so that on reexit of that first box that you collapse all the bullets so Sheets(pt).PivotTables("PivotTable1").PivotFields("ptData").ShowDetail = False
but that needs to be before you start counting items in the list.

Related

How can I refer to a data in a different row?

I've got an Excel file with N rows and M columns. Usually data are organized one per row, but it can happens that a data occupy more than a row. In this case how can I express that the second (or next) row has to refer to the first row?
In this example, AP.01 has got 5 rows of description, so how can I say that the other 4 rows refer also to the first code?
EDIT once that I did the association I have to export my Excel file into an Access DB. So I want to see the tables with the correct data.
If I have only one row for the description I wrote this code and it works:
If grid(r, 3).Text.Length > 255 Then
code.Description = grid(r, 3).Text.ToString.Substring(0, 252) + "..."
Else
code.Description = grid(r, 3).Text.ToString
End If
Instead if I have more than one row for the description I wrote this code and it doesn't work:
Do While grid(r, 1).ToString = ""
If grid(r, 1).ToString = "" And grid(r, 3).ToString IsNot Nothing Then
Dim s As String
s = grid(r, 3).ToString
code.Description = grid((r - 1), 3).ToString & s
End If
Loop
If it is a one-off, try the below. This will basically put a formula in every cell that refers to the cell immediately above it:
Select column A (from top until bottom of list (row N)
Press ctrl + g to open the GoTo dialogue
Press Special
Select Blanks from the radio buttons
The above will select all the blank cells in column A. Now enter = and press up arrow. Enter the formula by holding down ctrl while pressing enter. That will enter the same formula in every cell.
Try
Sub Demo()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet3") 'change Sheet3 to your data sheet
With .Range("A:A").SpecialCells(xlCellTypeBlanks)
.FormulaR1C1 = "=R[-1]C"
.Value = .Value
End With
End Sub
From your question I Guess that, you must be define a variable for last column Value. and check the value in respective column, if it is empty then use column value if not empty then take current value as last value.
'Dim LastValue as string
LastValue = sheet("SheetName").cells(i,"Column Name").value
for i = 2 to LastRow '>>>> here i am assume you run code in for loop from row to
'to last count row(LastRow as variable)
'Put your sheet name at "SheetName" and column index (like "A","B","C"...) at "Column Name"
if sheet("SheetName").cells(i,"Column Name").value <>"" then
LastValue = sheet("SheetName").cells(i,"Column Name").value
end if
'(Do your stuff using LastValue , you may generate lastvalue 1, lastvalue2 ..etc)
next'for loop end here

How to add multiple checkboxes in multiple columns (VBA)

I have a ListView with multiple columns. More precisely, the ListView contains 8 columns. 2 of them should be filled with checkboxes.
Currently only the first column contains checkboxes. It is defined as follows:
While Not rs.EOF
//first column with checkboxes
ListViewCustomer.ListItems.Add , , rs("Id")
ListViewCustomer.ListItems(ListViewCustomer.ListItems.Count).tag = rs("Status")
//second column etc.
ListViewCustomer.ListItems(ListViewCustomer.ListItems.Count).ListSubItems.Add , , rs("name")
....
//Here is the second column, which doesn't display the checkboxes
ListViewCustomer.ListItems(ListViewCustomer.ListItems.Count).ListSubItems.Add , , IIf(IsNull(rs("date_from")), "", rs("date_from"))
ListViewCustomer.ListItems(ListViewCustomer.ListItems.Count).tag = rs("Status2")
Wend
Do anyone have an idea how to add the checkboxes in the last column?
EDIT:
Is it possible to realize this column with adding via .Controls?
A ListView is a more expanded version of the ListBox control.
See ListBox control on msdn as well.
They both display records of rows (the ListView has more advanced formatting options). This however means that a record is a row. Therefore you select a row when you select one of the items.
The function of the checkbox is to allow the user to mark the row(s) that is the records(s) he selects.
Thus there is only one checkbox per row, at the front of the row.
Consider this code (this is Excel 2003 VBA, but gives you the idea):
Private Sub UserForm_Initialize()
Dim MyArray(6, 8)
'Array containing column values for ListBox.
ListBox1.ColumnCount = 8
ListBox1.MultiSelect = fmMultiSelectExtended
'Load integer values MyArray
For i = 0 To 5
MyArray(i, 0) = i
For j = 1 To 7
MyArray(i, j) = Rnd
Next j
Next i
'Load ListBox1
ListBox1.List() = MyArray
End Sub
You could do a custom ListBox or ListView if you really want. You could create a frame and put Labels and CheckBoxes on it. This is the only way to do this in Excel2003 where I tested. The ListBox object has no Controls child.
But this is more like a datagrid and not really a ListBox or ListView which by definition are a listing of records (rows).
Update:
I saw your update and that you really want to place the CheckBox at the end of the row.
If you only want one checkbox at the last row, you could do this custom checkbox. Again this is written for the ListBox, so need to convert it to your ListView if you want to.
Still requires a custom handling, but I had some time, so I did this code. See if you like it:
Private Sub ListBox1_Change()
For i = 0 To ListBox1.ListCount - 1
ListBox1.List(i, 3) = ChrW(&H2610)
Next i
ListBox1.List(ListBox1.ListIndex, 3) = ChrW(&H2611)
End Sub
Private Sub UserForm_Initialize()
Dim MyArray(5, 3)
'Array containing column values for ListBox.
ListBox1.ColumnCount = 4
ListBox1.MultiSelect = 0
ListBox1.ListStyle = 0
'Load integer values MyArray
For i = 0 To 5
MyArray(i, 0) = i
For j = 1 To 2
MyArray(i, j) = Rnd
Next j
MyArray(i, 3) = ChrW(&H2610)
Next i
'Load ListBox1
ListBox1.List() = MyArray
End Sub

Trying to remove specific items from an already populated Combobox VBA

In VBA I am writing a code that gathers information based off an initial input in a userform.
From the initial entrance point I want the code to go out and find the corresponding data and add it. I have that all working well.
But I am gathering the data from a pivot table and if the pivot table is open it returns "" spaces, "(blank)" and "Grand Total", which I want to get rid of.
My Current code is:
lcomboCount = Sheets(pt).PivotTables("Pivottable1").TableRange2.Rows.Count
For i = 1 To lcomboCount
datapoint = Sheets(pt).PivotTables("PivotTable1").PivotFields("combo").LabelRange.Offset(i, 0).Value
UserForm1.ComboBox.AddItem Sheets(pt).PivotTables("PivotTable1").PivotFields("combo").LabelRange.Offset(i, 0)
Next i
For i = 0 To Me.ComboBox.ListCount - 1
If Me.ComboBox = "" Or Me.ComboBox = "Grand Total" Or Me.ComboBox = ("(blank)") Then
Me.ComboBox.RemoveItem (i)
End If
Next i
I had a Msgbox in there at one point to see if my values were reading correctly and they were.
You just need to .List(i) when you test the values stored into the ComboBox.
Also I changed the "direction" (see second comment for details) of the second loop to avoid missing items.
Here is you revised code :
lcomboCount = Sheets(pt).PivotTables("PivotTable1").TableRange2.Rows.Count
For i = 1 To lcomboCount
datapoint = Sheets(pt).PivotTables("PivotTable1").PivotFields("combo").LabelRange.Offset(i, 0).Value
UserForm1.ComboBox.AddItem datapoint
Next i
For i = Me.ComboBox.ListCount - 1 To 0 Step -1
If Me.ComboBox.List(i) = "" Or Me.ComboBox.List(i) = "Grand Total" Or Me.ComboBox.List(i) = ("(blank)") Then
Me.ComboBox.RemoveItem (i)
End If
Next i

How to sort values of textboxes in vb?

I have two groups of textboxes, A and B and these are created dynamically.
My program should work like this:
1. A textboxes have corresponding B textboxes.
2. Then, B textboxes should be sorted by their values in ascending order.
3. Based on that order, the A textboxes' values will be sorted also.
EX:
A B
5 1
2 0
3 4
1 5
Output is: 2 5 3 1
Please help me out. Thanks!
Create arrays of the textbox controls you have and then write a simple bubble sort. Bubble sort is slow, but more than fast enough for small amounts of data.
Dim arrA() As Textbox = {a1, a2, a3, a4, a5}
Dim arrB() As Textbox = {b1, b2, b3, b4, b5}
Dim Changed as Boolean
Do
Changed = False
For i = 0 to arrB.Count - 2 'Stop at the second to last array item because we check forward in the array
If CInt(arrB(i).Text) > CInt(arrB(i + 1).Text) Then 'Next value is smaller than previous --> Switch values, also switch in arrA
Dim Temp as String = arrB(i + 1).Text
arrB(i + 1).Text = arrB(i).Text
arrB(i).Text = Temp
Temp = arrA(i + 1).Text
arrA(i + 1).Text = arrA(i).Text
arrA(i).Text = Temp
Changed = True
End If
Next
Loop Until Changed = False 'Cancle the loop when everything is sorted
Now the textbox values are sorted and you can display the results whereever you want.
To display the values in the labels, say called l1-l5:
Dim arrL() as Label = {l1, l2, l3, l4, l5}
For i = 0 to 4
arrL(i).Text = arrA(i).Text
Next

VB.NET DataGridView Not Showing Data

I have looked around quite a bit, and nothing seems to answer my question in particular. I have DataGridView in which I add rows and columns dependent on a certain record count of geospatial data that is held in ArcGIS. The data is then passed through to the gridview for editing.
So I do not use any databinding methods, rather it is a very manual process. I store data into a two-dimensional arrays, which indexes are based off of those certain data record counts.
After the loops are complete, the data should be stored in each cell dependent on index. The very last row that was populated is populated perfectly, yet the other 72 (or so) rows are blank.
Here is the code as follows:
This populates column headers (works great):
For i_FieldNum = 0 To pFields_1.FieldCount - 1
str_FieldName = UCase(pFields_1.Field(i_FieldNum).Name)
str_FieldAliasName = pFields_1.Field(i_FieldNum).AliasName
ReDim Preserve m_array_str_FieldNames(i_FieldNum)
ReDim Preserve m_array_str_FieldAliasNames(i_FieldNum)
m_array_str_FieldNames(i_FieldNum) = str_FieldName
m_array_str_FieldAliasNames(i_FieldNum) = str_FieldAliasName
i_FieldCount = i_FieldCount + 1
i_ColNum = i_FieldCount - 1
'If this is the "SHAPE", "FID", or "OBJECTID" field, remember it:
If (str_FieldName = "SHAPE") Then
m_i_FieldNum_Shape = i_FieldCount - 1
ElseIf (str_FieldName = "FID") Then
m_i_FieldNum_FID = i_FieldCount - 1
ElseIf (str_FieldName = "OBJECTID") Then
m_i_FieldNum_OBJECTID = i_FieldCount - 1
End If
'Store the field name in the top row:
grid_Data.ColumnCount = i_FieldCount
grid_Data.Columns.Item(i_ColNum).HeaderText = str_FieldName
ReDim Preserve m_array_l_FieldColLengths(i_ColNum)
m_array_l_FieldColLengths(i_ColNum) = pFields_1.Field(i_FieldNum).Length
Next i_FieldNum
This populates the two-dimensional array:
Do Until pFeat_1 Is Nothing
'Until we run out of features ...
i_FeatCount = i_FeatCount + 1
For i_FieldNum = 0 To pFields_1.FieldCount - 1
'If the field is recorded as a shape
If (i_FieldNum = m_i_FieldNum_Shape) Then
array_Data(i_FeatCount - 1, i_FieldNum) = "<Shape>"
Else
'If the value of the field is null
If IsNothing(pFeat_1.Value(i_FieldNum)) Or pFeat_1.Value(i_FieldNum).ToString = "" Then
array_Data(i_FeatCount - 1, i_FieldNum) = "<Null>"
Else
array_Data(i_FeatCount - 1, i_FieldNum) = pFeat_1.Value(i_FieldNum).ToString
End If
End If
Next i_FieldNum
'End If
'Move to the next feature (if any).
pFeat_1 = pFeatCursor_1.NextFeature
Loop
This is suppose to display the data:
For i_RowNum = 0 To i_FeatCount - 1
'Add a new row to the grid:
grid_Data.RowCount = i_RowNum + 2
For i_ColNum = 0 To pFields_1.FieldCount - 1
grid_Data.Item(i_ColNum, i_RowNum + 1).Value = array_Data(i_RowNum, i_ColNum)
Next i_ColNum
Next i_RowNum
Everything runs and compiles perfectly, although as I stated before, only the last row's data is shown (which is populated properly).
If anyone can help figure out why only one row is populated, it would be more than appreciated.
Thank You,
Logan
Check your updated section -This is suppose to display the data: If you data is correctly set then as per my guess it making grid to show wrong data. Modify it as per your columns in your grid that you have added. Or you can create column names string array to put data in particular cells. as dgvr.Cells(columnsArray[index]).Value = array[,]
For i_RowNum = 0 To i_FeatCount - 1
'Add a new row to the grid:
DataGridViewRow dgvr = new System.Windows.Forms.DataGridViewRow();
dgvr.CreateCells(grid_Data)
For i_ColNum = 0 To pFields_1.FieldCount - 1
dgvr.Cells(i_ColNum).Value = array_Data(i_RowNum, i_ColNum)
Next i_ColNum
grid_Data.Rows.Add(dgvr)
Next i_RowNum
Ref: Adding a New Row to DataGridView and How to: Manipulate
Rows in the Windows Forms DataGridView Control
See here, each time you increment the row count its clearing out the data:
DataGridView1.RowCount += 1
DataGridView1.Item(0, 0).Value = "a value"
DataGridView1.RowCount += 1
DataGridView1.Item(0, 1).Value = "the previous value has been wiped"
To fix your code without any major changes, just use this method to add rows:
grid_Data.Rows.Add(paramArray)
or even easier put this line above the for loop and set the number of rows before you fill them in:
grid_Data.RowCount = i_FeatCount - 1