VBA use value to count columns avoiding activecell.column - vba

I am trying to run a public value from starting the workbook to determine the column number to not use activecell.column. So I got:
Public CurrentColumn As Single
At the top outside the subroutine in ThisWorkbook and
CurrentColumn = ActiveCell.Column
inside the subroutine
Then I have buttons that are supposed to move to go left and right through columns and add or subtract 1 to the initial currentcolumn value.
CurrentColumn = CurrentColumn + 1
MsgBox CurrentColumn
But it seems that it doesn't actually add 1, because the message box shows "1" and that's not the correct column number because initial CurrentColumn is "3"
What am I doing wrong?
After this, I intend to replace
Worksheets("Machine Layout").Cells(9, ActiveCell.Column)
with something like
Worksheets("Machine Layout").Cells(9, CurrentColumn)
Could someone, please, help me figure this one out?

Related

Listbox Multiselect add to next available blank cell & remove from original range

Hopefully someone can help me? I have 2 list boxes RndAdd1 & RndEdit1. I want to be able to multi select items in RndAdd1 and then click Button1 and it loops through selected items and one at a time adds them to the new range (first blank cell) until all items added. Then remove all the values just added from the original range. (basically move from Column A to Column B for Monday, Column C to D for Tuesday and so on)
I also have another variable set (which day of the week) I have the following code I was going to place on the button then nest a series of if/Elseif statements.
The trouble I'm having currently is that it posts the first value in the first blank cell, then the 2nd value overwrites the first value and so on until only the final value is now visible in the new range. This is probably a simple fix and I'm just not thinking of it in the correct way!
Dim lItem As Long
For lItem = 0 To RndAdd1.ListCount - 1
If RndAdd1.Selected(lItem) = True Then
If ComboBox1.Value = "Monday" Then
Sheets("Setup").Range("B65536").End(xlUp)(0, 1) = RndAdd1.List(lItem)
RndAdd1.Selected(lItem) = False
End If
End If
Next
RndAdd1.Clear
RndEdit1.Clear
ComboBox1.Clear
ComboBox1.List = Array("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")
ComboBox1.Value = "Monday"
'Tuesday Repeat Code but with different range to take round numbers from
I'm on my phone so cannot post code buy maybe this can help you:
Dim TargetRange as range
Set TargetRange = thisworkbook.sheets(1).range("A1") 'or whereever you want it
Do until IsEmpty(TargetRange.value)
Set targetrange = targetrange.offset(1,0)
Loop
TargetRange.value = "your value here"
This loops down until it finds an empty cell
Hope it helps
substitute
Sheets("Setup").Range("B65536").End(xlUp)(0, 1) = RndAdd1.List(lItem)
with
With Sheets("Setup")
.Range(.Rows.Count, "B").End(xlUp).Offset(1) = RndAdd1.List(lItem)
End With

Naming the non-empty cells of a column as the previous column's values

So what I want is a button that when pressed will automatically name the right hand column cells the left hand column values, my code at the moment looks something like this,
Private Sub CommandButton1_Click()
Range("F3").Name = Range("E3")
Range("F4").Name = Range("E4")
Range("F5").Name = Range("E5")
Range("F6").Name = Range("E6")
End Sub
I'm new to using VBA and have looked around a little but couldn't find what I wanted to achieve. Just want a simple solution which can automatically do what my code already does without having to be specific about cell rows.
I imagine that there will be either a while or for loop to repeat over many rows and an if statement for the code not running if a cell is empty.
Basically I want the command to run something like below but don't quite know how to write it in excel VBA myself.
for j=3:100
if F(j) = non empty
F(j).name = E(j)
else end
next j
end
Image below shows the end result :
From your sample image this looks like it should work.
Option Explicit
Sub name_eff()
Dim rw As Long
With Worksheets("Sheet6")
For rw = 2 To Application.Min(.Cells(.Rows.Count, "E").End(xlUp).Row, _
.Cells(.Rows.Count, "F").End(xlUp).Row)
If Application.CountA(.Cells(rw, "E").Resize(1, 2)) = 2 Then _
.Cells(rw, "F").Name = .Cells(rw, "E").Text
Next rw
End With
End Sub

Delete rows based on range possible mistake

I'm trying to delete rows on one worksheet based on a range in another worksheet. I think the problem here is probably something simple based on my limited VBA experience. Here is the code I've written:
Sub LimitedElements()
imax = ActiveSheet.Cells.SpecialCells(xlCellTypeLastCell).Row
For i = 2 To imax
If Sheets("test").Cells(j, 1).Value = Sheets("Limited Elements").Range("A1:A10") Then
Rows(i).EntireRow.Delete
End If
Next i
End Sub
I get a message saying "Application-defined or object-defined error".
Can anyone tell me what I'm doing wrong? Or if this is just a dumb way to do this and I should be doing it differently?
Please see if below works for you:
Sub LimitedElements()
Dim imax As Integer
Dim a As Variant
Dim b As Range
Dim c As Object
Dim d As Integer
imax = ActiveSheet.Cells.SpecialCells(xlCellTypeLastCell).Row
For i = 2 To imax
a = Sheets("test").Cells(i, 1).Value
Set b = Sheets("Limited Elements").Range("A1:A10")
Set c = b.Find(What:=a, LookIn:=xlValues)
If Not c Is Nothing Then
Sheets("test").Rows(i).EntireRow.Delete
i = i - 1
imax = imax - 1
End If
Next i
End Sub
Noted that it is not fine tuned and is intended to give you an understanding on how to approach the solution.
I added code to decrement i. I think I understand that the code can't tell which worksheet I'm specifying for deleting the row but I'm not sure what to do about it. I tried changing "Rows(i).EntireRow.Delete" to "Sheets("test").Rows(i).EntireRow.Delete" but I'm not sure if that's the right thing to do or not.
Some extra details to make things clearer:
Sheet "test" has about 1000 rows with unique numbers in column A. Sheet "Limited Elements" has about 100 rows with unique numbers column A. I want it it delete the rows in "test" that have values in column A that match the column A values in "Limited Elements".
Sub LimitedElements()
imax = ActiveSheet.Cells.SpecialCells(xlCellTypeLastCell).Row
For i = 2 To imax
If Sheets("test").Cells(i, 1).Value = Sheets("Limited Elements").Range("A1:A10") Then
Sheets("test").Rows(i).EntireRow.Delete
i = i - 1
imax = imax - 1
End If
Next i
End Sub
I think the original problem was that I had Cells(j,1) instead of cells(i,1). Now I've fixed that but it gives me a type mismatch error which I think is due to comparing a single cell to a range.
At this point I think I'm just lost. I can't figure out how to change it so it works and does what I want it to do.

VBA Excel: Show visible cells in listbox only

I have the below mentioned code, I am trying to load filtered cells only into the listbox but I don't know why the below mentioned code is not functional.
Legend:
PatternSearchButton is a button
PatternTextBox is a textbox by which the user enters a value Which the Sheet will filter.
WsLookup is a function which selects the sheet (completely functional)
Private Sub PatternSearchButton_Click()
Dim PatternInput As String, PatternCounter As Double, WsSelector As Worksheet
PatternInput = PatternTextBox.Value
Set WsSelector = WsLookup(GSMListType.Value)
WsSelector.Range("F:F").AutoFilter Field:=1, Criteria1:=PatternInput
PatternCounter = Application.WorksheetFunction.Subtotal(4, WsSelector.Range("F:F"))
With AvailableNumberList
.Clear
For k = 2 To PatternCounter + 1
.AddItem WsSelector.Range("A" & k).SpecialCells(xlCellTypeVisible).Value
Next k
End With
End Sub
You're are using PatternCounter as the upper limit in your For .. Next but this is being set using the MAX (e.g. 4) subfunction of SUBTOTAL. This might work on sequential numbers in an unfiltered list but it is unlikely to be accurate in a filtered list. Using the COUNT (2/102) or COUNTA (3/103) subfunction might be more appropriate.
You were using SUBTOTAL(4, ...) so I would assume that you are dealing with numbers. Use a straight count on numbers on visible cells in column F and modify the remainder of the code to resemble this.
PatternCounter = Application.WorksheetFunction.Subtotal(2, WsSelector.Range("F:F"))
With WsSelector.cells(1,1).currentregion.offset(1,0).SpecialCells(xlCellTypeVisible)
AvailableNumberList.Clear
For k = 1 To PatternCounter
AvailableNumberList.AddItem .cells(k, 1).Value
Next k
End With
The problem might stem from the fact that you add to the list box the value of a special cell that might not exist if the cell is hidden.
Try for the body of the For loop:
' ... previous code '
If Not WsSelector.Rows(k).EntireRow.Hidden Then
.AddItem WsSelector.Cells(k, 1).Value
End If
' rest of the code ... '
Also, make sure that AvailableNumberList points to the correct object in your code.

Removing rows based on matching criteria

I have a dated CS degree so I understand the basics of VB but I don't write macros very often and need help solving a particular condition. (...but I understand functions and object oriented programming)
Assume the following:
- Column A contains reference ID's in alphanumeric form, sorted alphabetically.
- Column B contains strings of text, or blanks.
I'm trying to write a macro that automatically removes any extra rows for each unique reference number based on the contents of the "Notes" in column B. The problem is that if column A has multiple instances of a unique ref number, I need to identify which row contains something in column B. There is one catch: it is possible that the reference number has nothing in column B and should be retained.
To explain further, in the following screenshot I would need to:
Keep the yellow highlighted rows
Delete the remaining rows
I tried to show various configurations of how the report might show the data using the brackets on the right and marked in red. Its difficult to explain what I'm trying to do so I figured a picture would show what I need more clearly.
This task is making the report very manual and time consuming.
it's pretty simple
you just go throug the rows and check whether this row needs to be deleted, an earlier row with this id needs to be deleted or nothing should happen.
in my example i mark these rows and delete them in the end.
Sub foo()
Dim rngSelection As Range
Dim startingRow As Integer
Dim endRow As Integer
Dim idColumn As Integer
Dim noteColumn As Integer
Dim idValuableRow As New Dictionary
Dim deleteRows As New Collection
Set rngSelection = Selection
startingRow = rngSelection.Row
endRow = rngSelection.Rows.Count + startingRow - 1
idColumn = rngSelection.Column
noteColumn = idColumn + 1
For i = startingRow To endRow
currentID = Cells(i, idColumn)
If idValuableRow.Exists(currentID) Then
If Trim(idValuableRow(currentID)("note")) <> "" And Trim(Cells(i, noteColumn)) = "" Then
deleteRows.Add i
ElseIf idValuableRow(currentID)("note") = "" And Trim(Cells(i, noteColumn)) <> "" Then
deleteRows.Add idValuableRow(currentID)("row")
idValuableRow(currentID)("row") = i
idValuableRow(currentID)("note") = Cells(i, noteColumn)
End If
Else
Dim arr(2) As Variant
idValuableRow.Add currentID, New Dictionary
idValuableRow(currentID).Add "row", i
idValuableRow(currentID).Add "note", Cells(i, noteColumn)
End If
Next i
deletedRows = 0
For Each element In deleteRows
If element <> "" Then
Rows(element - deletedRows & ":" & element - deletedRows).Select
Selection.Delete Shift:=xlUp
deletedRows = deletedRows + 1
End If
Next element
End Sub
it could look something like this. the only thing you need is to add Microsoft Scripting Runtime in Tools/References