How to make a cell reference function - excel

Sub Nowe
X = 1
For i = 1 to 5
If Cells (i, X).Value = "What" Then
Cells (i+1, 6).Interior.ColorIndex = 6
End If
Next i
End Sub
I am showing an error on this snippet: "If Cells (i, X).Value = "What" Then"
I would like to make a reference but as functions

When I tried to run your code, the only error I got was related to not declaring x and i variables.
Option Explicit
Sub Nowe()
Dim x As Integer
Dim i As Integer
x = 1
For i = 1 To 5
If Cells(i, x).Value = "What" Then
Cells(i + 1, 6).Interior.ColorIndex = 6
End If
Next i
End Sub

Related

Countif using Offset

I'm working with this code which Will help me to go over a group of columns depending on the date.
The thing is, I'm trying to make my file to check the frecuency of the values and count the values that "Cumplen".
I mean, if the values in cells(x,"c") are "Diarios" then count the quantity of "Cumple" in cells(x,"w").
I'm using offset function cuz it allows me to go over more than one column at a time.
Thanks.
Sub pruebaestadisticas()
Application.ScreenUpdating = True
Set r = ThisWorkbook.Sheets("Seguimiento").Rows(2).Cells
fila = ThisWorkbook.Sheets("Seguimiento").Range("A" & Rows.count).End(xlUp).Row
With ThisWorkbook.Sheets("Seguimiento")
For x = 4 To fila
For Each c In r
If c.Value = "3/1/2022" Then
If .Cells(x, "C").Value = "Diario" Then
c.Offset(fila - 1, 1).Value = WorksheetFunction.CountIf(.Range(c.Offset(x - 2, 1), c.Offset(x - 2, 1)), "Cumple")
End If
End If
Next c
Next x
End With
End Sub
This is the same code in a direct way:
Sub pruebaestadisticas2()
Application.ScreenUpdating = True
Set r = ThisWorkbook.Sheets("Seguimiento").Rows(2).Cells
fila = ThisWorkbook.Sheets("Seguimiento").Range("A" & Rows.count).End(xlUp).Row
ThisWorkbook.Sheets("Seguimiento").Range("W33").Value = ""
With ThisWorkbook.Sheets("Seguimiento")
For x = 4 To fila
For Each c In r
If c.Value = "3/1/2022" Then
If .Cells(x, "C").Value = "Diario" Then
.Range("W33").Value = WorksheetFunction.CountIf(.Cells(x, "W"), "Cumple")
End If
End If
Next c
Next x
End With
End Sub

Check values in columns, allowing for not all columns being present

I'm trying to clean up raw data exported from an online database.
There can be up to five columns. If all cells in a row have a value of 0, I want to delete that row.
When the user exports the data, they can choose to exclude columns, and the columns can be in any order.
For example, if the data contains only two of the possible five columns, I want to check just those two for 0s.
Could do a a big loop looking at every row and seeing if all 5 columns in that row are blank
Sub test()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("sheetname")
Dim LastRow As Integer
LastRow = sh.UsedRange.Rows.Count - 1
For i = 1 To LastRow
If (sh.Cells(i, 1).Value = "" And sh.Cells(i, 2).Value = "" And sh.Cells(i, 3).Value = "" And _
sh.Cells(i, 4).Value = "" And sh.Cells(i, 5).Value = "") Then
sh.Cells(i, 1).EntireRow.Delete
i = i - 1
Dim newLastRow As Integer
newLastRow = sh.UsedRange.Rows.Count - 1
If i = newLastRow Then
Exit For
End If
End If
Next i
MsgBox ("Done")
End Sub
#kyle campbell, thank you for your input! It didn't quite get me there, but it did get my wheels turning. Here is the solution I came up with, if anyone's curious:
I set a variable to represent the column number for each of the 5 possible columns using Range.Find. If the Find came up with nothing, I set the variable to 49, since the maximum number of columns this report can have is 48.
Then I did a nested If to test if the value in each cell was either 0 or null (because if the column number is 49, there won't be any data there). If all Ifs were true, I deleted the row. I also added a counter and message box, just to make sure this worked.
Sub DeleteRows()
Dim O As Long
Dim E As Long
Dim H As Long
Dim B As Long
Dim P As Long
lRow = Range("A1").CurrentRegion.Rows.Count
If Range("1:1").Find("SUM(OBLIGATIONS)") Is Nothing Then
O = 49
Else
O = Range("1:1").Find("SUM(OBLIGATIONS)").Column
End If
If Range("1:1").Find("SUM(EXPENDITURES)") Is Nothing Then
E = 49
Else
E = Range("1:1").Find("SUM(EXPENDITURES)").Column
End If
If Range("1:1").Find("SUM(HOURS)") Is Nothing Then
H = 49
Else
H = Range("1:1").Find("SUM(HOURS)").Column
End If
If Range("1:1").Find("SUM(BUDGET_RESOURCES)") Is Nothing Then
B = 49
Else
B = Range("1:1").Find("SUM(BUDGET_RESOURCES)").Column
End If
If Range("1:1").Find("SUM(PRIOR_YEAR_RECOVERY)") Is Nothing Then
P = 49
Else
P = Range("1:1").Find("SUM(PRIOR_YEAR_RECOVERY)").Column
End If
Dim j As Integer
j = 0
For i = lRow To 2 Step -1
If Cells(i, O) = 0 Or Cells(i, O) = "" Then
If Cells(i, E) = 0 Or Cells(i, E) = "" Then
If Cells(i, H) = 0 Or Cells(i, H) = "" Then
If Cells(i, B) = 0 Or Cells(i, B) = "" Then
If Cells(i, P) = 0 Or Cells(i, P) = "" Then
Rows(i).Delete
j = j + 1
End If
End If
End If
End If
End If
Next i
MsgBox "Macro complete, " & j & " lines deleted."
End Sub

Looping through an array in Excel

Trying to loop through a sheets"data".Range"AM1:AS12" and copy the data to range beginning at BD1 as long as the data doesn't equal "#N/A"
My code works with copying the first column, but doesn't do anything with the data after that. Where am I going wrong?
Set S2 = Sheets("data").Range("AM:AM")
Set S3 = Sheets("data").Range("BD:BD")
Dim i As Integer, j As Integer
j = 1
For i = 1 To 12
If S2.Cells(i, 1).Value <> "#N/A" Then
S3.Cells(j, 2).Value = S2.Cells(i, 1).Value
j = j + 1
End If
Next i
Replace:
<> "#N/A"
By:
Not(Application.WorksheetFunction.IfNa(...))
This works when i tested it.
Sub CopyCell()
Set S2 = Sheets("data").Range("A:A")
Set S3 = Sheets("data").Range("M:M")
Dim i As Integer, j As Integer
For j = 1 To 2
For i = 1 To 12
If S2.Cells(i, j).Value <> "#N/A" Then
S3.Cells(i, j).Value = S2.Cells(i, j).Value
End If
Next i
Next j
Call DeleteBlank
End Sub
Sub DeleteBlank()
Dim x As Integer
Dim y As Integer
For y = 13 To 16 'Range numbers for the columns the data is copied to
For x = 1 To 10 ' Number of cells of data you want to loop through
If Cells(x, y).Value = "" Then
Cells(x, y).Delete Shift:=xlUp
End If
Next x
Next y
End Sub
the best thing to is not to check if it is equal to "#N/A"
The best is to check if it is an error : If Not (IsError(S2.Cells(i, 1).Value)) Then

How to search multiple worksheets?

I search any text within Worksheet2 and display the results in ListBox1.
Private Sub SearchButton_Click()
'ListBox1.Clear
ListBox1.RowSource = ""
ListBox1.ColumnHeads = False
'listbox column headers
Me.ListBox1.AddItem
For A = 1 To 8
Me.ListBox1.List(0, A - 1) = Sheet2.Cells(1, A)
Next A
Me.ListBox1.Selected(0) = True
'Populating listbox from search
Dim i As Long
For i = 2 To Sheet2.Range("A100000").End(xlUp).Offset(1, 0).Row
For j = 1 To 8
H = Application.WorksheetFunction.CountIf(Sheet2.Range("A" & i, "H" & i), Sheet2.Cells(i, j))
If H = 1 And LCase(Sheet2.Cells(i, j)) = LCase(Me.TextBox2) Or H = 1 And _
Sheet2.Cells(i, j) = Val(Me.TextBox2) Then
Me.ListBox1.AddItem
For X = 1 To 8
Me.ListBox1.List(ListBox1.ListCount - 1, X - 1) = Sheet2.Cells(i, X)
Next X
End If
Next j
Next i
End Sub
I want to search multiple worksheets instead but don't know how to achieve this without changing the code completely.
You're going to have to change the reference to Sheet2 if you want to look at multiple sheets. There's no way around that. But, it will make your code more flexible. Start by doing this:
Private Sub SearchButton_Click()
'ListBox1.Clear
ListBox1.RowSource = ""
ListBox1.ColumnHeads = False
'listbox column headers
Me.ListBox1.AddItem
For A = 1 To 8
Me.ListBox1.List(0, A - 1) = Sheet2.Cells(1, A)
Next A
Me.ListBox1.Selected(0) = True
Dim ws As Worksheet 'This is the new line of code where you define your worksheet
Set ws = ActiveWorkbook.Sheet2 'Replace all references below to Sheet2 with this
'Populating listbox from search
Dim i As Long
For i = 2 To ws.Range("A100000").End(xlUp).Offset(1, 0).Row
For j = 1 To 8
H = Application.WorksheetFunction.CountIf(ws.Range("A" & i, "H" & i), Sheet2.Cells(i, j))
If H = 1 And LCase(Sheet2.Cells(i, j)) = LCase(Me.TextBox2) Or H = 1 And _
ws.Cells(i, j) = Val(Me.TextBox2) Then
Me.ListBox1.AddItem
For X = 1 To 8
Me.ListBox1.List(ListBox1.ListCount - 1, X - 1) = Sheet2.Cells(i, X)
Next X
End If
Next j
Next i
End Sub
Now that you're generalized your Sub, you can modify the value of ws to repeat the code as much as you need to. If it is every sheet in your workbook, you can use a For Each loop, like
For Each ws In ActiveWorkbook
'All your code for the ws here
Next ws
Or, you can define the worksheets in an array beforehand.
Dim SheetList(0 to 2) As String
Dim k As Integer
SheetList(0) = "Sheet 2 Name"
SheetList(1) = "Sheet 4 Name"
SheetList(2) = "Sheet 3 Name"
SheetList(3) = "Sheet 6 Name"
For k = LBound(SheetList) To UBound(SheetList)
ws = ActiveWorkbook.Sheets(SheetList(k))
'The rest of your code from above
Next k
You didn't specify in your question what kind of sheets how many, or how they are organized. But, these options should be enough to get you where you are trying to go.

in vba how to define array and compare them?

i have 2 sheets , i want to find the same rows in 2 sheets , so i put the first row in array , and by a for next i define the first array ...then i define another array from second sheet , then i compare them .... why it doesn't work?
Sub compare()
Dim n(4) As Variant
Dim o(4) As Variant
Dim i As Integer
For i = 3 To 20 'satrha
For j = 2 To 4 'por kardan
n(j) = Sheets("guys").Cells(i, j)
Next 'por kardan
k = 3
Do 'hhhh
For Z = 2 To 4 'por dovomi
o(Z) = Sheets("p").Cells(k, Z)
Next 'por dovomi
If n(j) = o(Z) Then
Sheets("guys").Cells(i, 1) = Sheets("p").Cells(k, 2)
flag = True
Else
flag = False
k = k + 1
End If
Loop Until flag = False 'hhhhh
Next 'satrha
End Sub
Guessing from your existing code, my following code will copy the value from sheet "p" column B into sheet "guys" column A when a match is found.
Sub compare()
Dim i As Integer
Dim j As Integer
Dim l As Integer
l = Sheets("p").Range("B65535").End(xlUp).Row
Debug.Print l
For i = 3 To 20
For j = 3 To l
If Sheets("guys").Cells(i, 2).Value = Sheets("p").Cells(j, 2).Value And _
Sheets("guys").Cells(i, 3).Value = Sheets("p").Cells(j, 3).Value And _
Sheets("guys").Cells(i, 4).Value = Sheets("p").Cells(j, 4).Value Then
Sheets("guys").Cells(i, 1).Value = Sheets("p").Cells(j, 2).Value
Exit For
End If
Next
Next
End Sub
Noted that I explicitly said Value in my code. That will copy the computed value (e.g. result of a formula) instead of the "original" content.

Resources