VBA Excel formula with dynamic table name - excel-formula

I have an issue for writing a formula in VBA
the formula in Excel is very simple, if the word Test appears in a row of one of my 4 tables, then give me the sum of the column4 :
=SUMIF(Table1[Column1]:Table4[Column1],"Test",Table1[Column4]:Table4[Column4])
In VBA, it would be (and it works) :
ws.Range("B1").Formula ="=SUMIF(Table1[Column1]:Table4[Column1],""Test"",Table1[Column4]:Table4[Column4])"
My issue is that I have a dynamic number of tables, so my biggest table is "Table" & i
I really don't know how to write in VBA the formula, I always have an error:
ws.Range("B1").Formula ="=SUMIF(Table1[Column1]:""Table"" & i &""[Column1]"",""Test"",Table1[Column4]:""Table"" & i &""[Column4]"")"
What is the best way to achieve this?
Sub Formula()
Dim ws As Worksheet
Dim i As Integer
Set ws = Worksheets(1)
i = ws.Range("A1")
If i = 1 Then
ws.Range("B1").Formula = "=SUMIF(Table1[Column1]:Table1[Column1],""Test"",Table1[Column3]:Table1[Column3])"
End If
If i = 2 Then
ws.Range("B1").Formula = "=SUMIF(Table1[Column1]:Table2[Column1],""Test"",Table1[Column3]:Table[Column3])"
End If
If i = 3 Then
ws.Range("B1").Formula = "=SUMIF(Table1[Column1]:Table3[Column1],""Test"",Table1[Column3]:Table3[Column3])"
End If
If i = 4 Then
ws.Range("B1").Formula = "=SUMIF(Table1[Column1]:Table4[Column1],""Test"",Table1[Column3]:Table4[Column3])"
'What I would like :
'ws.Range("B1").Formula = "=SUMIF(Table1[Column1]:Table" & i & "[Column1],""Test"",Table1[Column4]:Table" & i & "[Column4])"
End If
End Sub
Thanks a lot

Related

sum to last row minus 1 in VBA

In Excel, I have column M full of data and then at the bottom of the data, a header.
I need to sum all of column M minus that header, then put it in a column under that header.
I am new to macros and have been trying to figure it out to no prevail. here's what i have tried :
With Over65
Over65M = Over65.Range("M" & .Rows.Count).End(xlUp).Offset(-1, 0)
Over65.Range("M5:M1000").Find("").Formula = "=sum(M5:M" & Over65M & ")"
End With
Please help!
Maybe something like that (sorry, I needed to use Sheet1 as an example; feel free to change it):
Sub SumValues()
Dim Over65 As Worksheet
Dim Over65M As Long
Set Over65 = Sheets("Sheet1")
With Over65
Over65M = .Range("M" & .Rows.Count).End(xlUp).Row
.Range("M5:M1000").Find("").Formula = "=sum(M5:M" & Over65M - 1 & ")"
End With
End Sub

Excel VBA macro reading one column with differing text

I was tasked with creating a code that will check to see if internal hyperlinks in an excel spreadsheet worked. This code first changes the formulas that were on the spreadsheet and makes them actual hyperlinks (they were originally formulas linking the locations together). The problem that I have now is that I want to create hyperlinks ONLY if Column S has text. If it doesn't, I don't want the "E-COPY" text to be displayed. All of the text in Column S varies (not one line has the same characters), which is why I'm drawing a blank is to how I tell the program to only continue if it has any text, not anything specific. I am working with Excel 2016.
Also, I am doing this to 71935 and counting rows; is there a limit to how many it can go through? If so, what can I do about it?
Thank you!
Sub CreateHyperlinks()
Dim FN As Variant
Dim Path As Variant
Dim count As Variant
Sheets(1).Activate
count = WorksheetFunction.CountA(Sheets(1).Range("A:A"))
For i = 2 To count
If Range("AM" & i).Value = "Yes" And Columns("S") = Then
Range("E" & i).Value = ""
Path = Sheets(1).Range("R" & i).Value
FN = Sheets(1).Range("S" & i).Value
Sheets(1).Range("E" & i).Select
Selection.ClearFormats
Selection.Hyperlinks.Add Anchor:=Selection, Address:=Path & FN, TextToDisplay:="E-COPY"
Range("AM" & i).Value = " "
End If
Next i
End Sub
If you just need to check for any content in ColS then:
If Range("AM" & i).Value = "Yes" And Len(Range("S" & i).Value) > 0 Then
Few things:
'make a reference to the sheet you're working with
Dim ws As Worksheet
Dim wb As Workbook
Set wb = Excel.Application.ThisWorkbook
Set ws = wb.Worksheets(1)
'gets the absolute last row with data in it // ignores empty cells
count = ws.UsedRange.Rows.Count
personally, i hate working with named ranges, so i would suggest setting range references like so
what you wrote
Path = Sheets(1).Range("R" & i).Value
what i believe it should look like
Path = ws.Cells(i, 18).Value
if you want to test the type when working with variants, try this:
'tests the type associated with the variant. an 8 = string
If VarType(ws.Cells(i, 19).Value) = 8 Then
'do your thing
'tests if the value is null
ElseIf VarType(ws.Cells(i, 19).Value) = 0 Then
'do your other thing
here's a list of the vartype enumeration to help you out.
hope it helps!

Setting value to a cell on multiple sheets using Excel VBA

Sub Heading_Data()
num = 1
Sheets("Sheet1","Sheet2","Sheet3").Select
Range("A" & num).Select
ActiveCell.FormulaR1C1 = "Branch"
Range("B" & num).Select
ActiveCell.FormulaR1C1 = "Project"
Range("C" & num).Select
ActiveCell.FormulaR1C1 = "Customer"
End Sub
The above code works fine where in the value of A1, B1 and C1 in each of the three sheets get the values Branch, Project and Customer respectively.
I want to avoid using the Select before setting the values accordingly I modified the code to the following
Sub Heading_Data()
num = 1
Sheets("Sheet1","Sheet2","Sheet3").Select
Selection.Range("A" & num).Value = "Branch"
Selection.Range("B" & num).FormulaR1C1 = "Project"
Selection.Range("C" & num).FormulaR1C1 = "Customer"
End Sub
The above only set the value on Sheet1 but rest of the two sheets are set with blanks.
Kindly advise the correct way to set the value without using Select.
Looping through those sheets and setting the values for each one is the only solution I can think of.
Sub Heading_Data()
num = 1
sheetsArray = Array("Sheet1","Sheet2","Sheet3")
For Each sheetName in sheetsArray
Sheets(sheetName).Range("A" & num).Value = "Branch"
Sheets(sheetName).Range("B" & num).FormulaR1C1 = "Project"
Sheets(sheetName).Range("C" & num).FormulaR1C1 = "Customer"
Next sheetName
End sub

Excel Macro - pull cell function until the end of the table

I will use an example to illustrate my question:
I have many tables which their lines quantity is different.
I want to pull down the function until the end of the table.
For example:
A B
1 =1*2 // <- this is the function that I want to pull
2
3
4
The output should be:
A B
1 =1*2
2 =2*2
3 =3*2
4 =4*2
It is important that the pull length is determined by the last cell at column A (in this case it is 4)
Please also note that the function may be changed either, this should work for any function.
Thank you,
Doron
Here is an example of a macro that will autofill the value from cell B1 to the end of the column to the left of it (in this case column A).
Sub AutoFill()
Dim FillFrom As Range
Set FillFrom = ActiveSheet.Range("B1")
FillFrom.AutoFill Destination:=Range(FillFrom.Address, FillFrom.Offset(0, -1).End(xlDown).Offset(0, 1).Address)
End Sub
Try This:
Public Sub DoWhatIWantYouToDo()
Dim lr As Integer, i As Integer
lr = Sheets("Sheet1").UsedRange.Rows.Count
For i = 2 To lr
Sheets("Sheet1").Range("B" & i).Formula = "=" & " A" & i & "*2"
Next
End Sub

How to hide rows in VBA based on values in row, quickly

this is my first time using the site, so forgive me for any inept explaining. I have a working macro to hide/unhide rows based on content of the rows, I just want it to be faster. Using a check box, when the box is checked, all rows with an "x" in column D get unhidden, those without an "x" get hidden. Same thing happens when it is unchecked, except it references column C, not D.
Right now, this code works. It's just a little slower than I'd like, since I'm sharing this with a bunch of people. Any ideas for how to speed it up? I'm pretty darn new to VB (the internet is astoundingly wise and a good teacher), but that doesn't matter. I already improved the code - before it selected each row, then referenced the column, and it was awful. Any ideas to speed it up (preferably without moving the screen) would be great.
Thanks so much folks,
DS
Sub NewLuxCheck()
Dim x As Integer
NumRows = Range("A42", "A398").Rows.Count
Range("A42").Select
If ActiveSheet.Shapes("checkbox2").OLEFormat.Object.Value = 1 Then
For x = 42 To NumRows + 41 Step 1
If Worksheets("Base").Range("D" & x).Value = "x" Then
Worksheets("Base").Range(x & ":" & x).EntireRow.Hidden = False
Else
Worksheets("Base").Range(x & ":" & x).EntireRow.Hidden = True
End If
Next
Else
For x = 42 To NumRows + 41 Step 1
If Worksheets("Base").Range("C" & x).Value = "x" Then
Worksheets("Base").Range(x & ":" & x).EntireRow.Hidden = False
Else
Worksheets("Base").Range(x & ":" & x).EntireRow.Hidden = True
End If
Next
End If
MsgBox ("Done")
End Sub
You could use array formula and let Excel to return array with row-numbers where 'x' value occures. It will be quicker but you'll have to reorganise your code and create separate functions etc.
Here example where array formula finds rows whre in column 'D' the cell has value 'x'. Then string of this row numbers is created in form of "A1,A5,A10" ...means 'x' was found in rows 1,5,10. And finally Range(rowsJoind).EntireRow.Hidden is used for all the rows to be hidden/un-hidden in one step.
For rows with value different then 'x' you'll have to use formula like '=IF({0}<>""x"", ROW({0}), -1)'.
Sub test()
Dim inputRange As Range
Dim lastRow As Long
Dim myFormula As String
Dim rowsJoined As String, i As Long
Dim result As Variant
With Worksheets("Base")
lastRow = .Range("D" & .Rows.Count).End(xlUp).Row
Set inputRange = .Columns("D").Resize(lastRow)
Application.ReferenceStyle = xlR1C1
myFormula = "=IF({0}=""x"", ROW({0}), -1)"
myFormula = VBA.Strings.Replace(myFormula, "{0}", inputRange.Address(ReferenceStyle:=xlR1C1))
result = Application.Evaluate(myFormula)
result = Application.Transpose(result)
Application.ReferenceStyle = xlA1
For i = LBound(result) To UBound(result)
If (result(i) > -1) Then
rowsJoined = rowsJoined & "A" & result(i) & IIf(i < UBound(result), ",", "")
End If
Next i
.Range(rowsJoined).EntireRow.Hidden = False
End With
End Sub

Resources