How to define Property range.formula for two dimensional array - vba

I'm wondering if someone can explain how property range.formula works in more detail then vba basic help.
I would like to use this property to test if all cells are empty in range. (I know and I can type a plenty of other codes how to test it but I would like to find way how to do using this property).
So for example if I want to check all cell in range("A1:A10") I've only done it like this.
Private Sub cell_in_range()
Dim i As Integer
Dim iTest As Integer
i = 1
Do While i <= 10 And iTest = 0
iTest = VBA.Len(Sheet17.Range("A" & i).Formula)
If iTest > 0 Then
Call VBA.MsgBox("Not all cells empty")
End If
i = i + 1
Loop
If VBA.Len(shee17.Range("A" & i)) = 0 Then
Call VBA.MsgBox("All cells empty")
End If
End Sub
This works but what if I would like to check in this way for example range of cells range("A1:X1000")
Again I know that instead of range I can you nested do while loops and change cells index like cells(i,j)
but again I would like to do it using property range.formula
I spent an hours to google how to define formula for two dimensional array. Can anybody explain this topic in more detail.
Thanks,

Is this of any help ??
Sub formulatest()
Dim r As Range, rng As Range
Set rng = Range("A1:X1000")
For Each r In rng
If r.HasFormula Then
MsgBox "cell " & r.Address & " has a formula"
Exit Sub
End If
Next r
MsgBox "no cells have formulas"
End Sub
EDIT#1:
You don't need loops. For the range A1:B2:
Sub dural()
Dim rng As Range
Set rng = Range("A1:B2")
arr = rng.Formula
For Each a In arr
MsgBox a
Next a
End Sub

the .formula property is used to set or return the formula contained in a specific range. if the range contains multiple cells the property returns a bidimensional array.
I would use the following instruction
Application.Count(Range("A1:X1000"))
if it returns 0, all cells are empty.

Related

VBA - Adding to an existing formula

I have various formulas in a spreadhseet that I need to convert to a different unit of measure.
Some are as simple a value such as 889 and others are a formula such as the below;
=Incision_Point_1x+(Arm_Depth_1-Graphic_Radius)
I'd like to use VBA to quickly take the existing formula / value and convert it to;
=(889/Unit_of_Measure_Multiplier)
=(Incision_Point_1x+(Arm_Depth_1-Graphic_Radius)/Unit_of_Measure_Multiplier)
How can I do this?
I used the following code;
Range("B3") = "=(" & Range("B3") & "/" & "Unit_Of_Measure_Multiplier)"
Which works perfectly when you have a whole number but deletes the formula and replaces it with a value for my second example, which defeats the point.
Additionally, how do I then apply this to a large data range? i.e. apply it to range B3:D100?
Try this code:
Sub test1()
For Each cl In Range("B3:D100")
If cl.HasFormula Then
v = Mid(cl.Formula, 2) 'remove leading =
Else
v = cl.Value
End If
frm = "=(" & v & "/Unit_Of_Measure_Multiplier)"
Debug.Print frm 'check that this is what you want
cl.Formula = frm
Next
End Sub
Please, try the next way:
Sub adaptFormula()
Dim rngFormula As Range, cel As Range
On Error Resume Next 'for the case of no formula in the range...
Set rngFormula = Range("B3:D100").SpecialCells(xlCellTypeFormulas)
On Error GoTo 0
If rngFormula Is Nothing Then Exit Sub
For Each cel In rngFormula.cells 'iterate only between cells having a formula
If InStr(cel.Formula, "=(Inc") > 0 Then
cel.Formula = Replace(cel.Formula, "Incision_Point_1x+(Arm_Depth_1-Graphic_Radius)", "889")
End If
Next
End Sub
Please, check if "Incision_Point_1x+(Arm_Depth_1-Graphic_Radius)" as you show us, is not "Incision_Point_1x + (Arm_Depth_1-Graphic_Radius" (spaces in front and after "+"), as it looks to me more probably. If so, please adapt the string to be replaced according to your real formula string...

add href hyperlinks to excel range programmatically

This has got to be a common problem with a simple answer but I can't seem to turn up a solution. Using an Excel macro, I examine a website home page for links and put those links into a range in Excel.
Now I want to make those values into hyperlinks.
Set allLinks = objIE.document.GetElementsByTagName("A")
For Each link In allLinks
If InStr(link.href, inspectOneCat) Then
inspectLink(linkCount) = link
linkCount = linkCount + 1
End If
Next
In the next step, the one-dimensional array is converted to a two-dimensional array with a descriptive column in inspectLink(i,0) and the link values in inspectLink(i,1). Then the array loaded into a range, like this:
Sheets("Awesomepova").Range("a2:b300").Value = inspectLink
This works. But these links appear as values, not as hyperlinks. I want to do something like this:
'Sheets("Awesomepova").Hyperlinks.Add Sheets("Awesomepova").Range("a2:b300"), Sheets("Awesomepova").Range("a2:b300").Value
This doesn't work. But I went into the worksheet manually and changed the first cell so it was hyperlinked and I noticed that even when I reload the entire range programmatically, the hyperlink remains, so I'm thinking this is a characteristic of the cell format, not the actual data in the cell.
Maybe the problem can be fixed by applying the same formatting to all the cells in the column where the rule is to use the cell value as the hyperlink value.
This is the equivalent using a For i... loop
Public Sub TestMe()
Dim myArr As Variant
Dim i As Long
myArr = Array("www.bbc.com", "www.stackoverflow.com")
For i = 0 To UBound(myArr)
Worksheets(1).Cells(i + 1, 1).Hyperlinks.Add Worksheets(1).Cells(i + 1, 1), myArr(i)
Next i
End Sub
Considering that you already have crawled the websites in the array inspectLink, something like this works:
Public Sub TestMe()
Dim myArr As Variant
Dim myUnit As Variant
Dim myCell As Range
myArr = Array("www.sugarpova.com", "www.stackoverflow.com")
Set myCell = Worksheets(1).Cells(1, 1)
For Each myUnit In myArr
myCell.Hyperlinks.Add myCell, myUnit
Set myCell = myCell.Offset(1, 0)
Next myUnit
End Sub
It prints working hyperlinks on the first worksheet:
Try looping through a2:b300 one hyperlink at a time using Hyperlinks.add instead of trying to force Hyperlinks.Add to apply to an entire range in one command:
For Row = 2 To 300
URL = Sheets("Awesomepova").Range("B" & Row).Value
Text = Sheets("Awesomepova").Range("A" & Row).Value
If URL <> "" Then
Set result = Sheets("Awesomepova").Hyperlinks.Add(Range("C" & Row), URL, "", TextToDisplay:=Text)
End If
Next
Several ways you can do the same. How about this?
Sub Demo()
Dim storage As Variant, cel As Variant, r&
storage = [{"https://www.google.com/", "https://www.yahoo.com/","https://www.wikipedia.org/"}]
For Each cel In storage
r = r + 1: Cells(r, 1).Hyperlinks.Add Cells(r, 1), cel
Next cel
End Sub

Setting variables VBA

complete novice here
I started some VBA a few days ago, I have simple question but cant seem to find what I am doing wrong.
I am trying to make a button which will take the coordinates of the active cell and compare them to another worksheet to retrieve a specific value from another table.
I set variables to the active cell column and row, I want to do this so I can later compare these locations to another worksheet and get the value at a specified position on another worksheet.
So far I have written simply what I could find on the internet as I have no formal training.
The msgbox at the end is just to test whether or not it actually picks up the reference.
Sub CommandButton1_Click()
Dim Arow As Range
Dim Acol As Range
Set Arow = Worksheets("Sheet1").Range(ActiveCell.Row)
Set Acol = Worksheets("Sheet1").Range(ActiveCell.Column)
MsgBox (Arow)
End Sub
So far I have error run-time error '1004' Application defined or object defined error highlighting the 4th Row. If anyone could help me solve this or redirect me to some help it would be much appreciated.
I think this won't work, you should put there
Set arow = Worksheets("Sheet1").Range(ActiveCell.Row & ":" & ActiveCell.Row)
Putting there simply number won't work. For the column, you should put there somethong like C:C. For getting letter of column, see this qestion: Function to convert column number to letter?
For more information about Range property, please see official documentation https://msdn.microsoft.com/en-us/library/office/ff836512.aspx.
The thing is, that you have to supply either the address in so called A1 reference, which is "A1", or "$A$1" or name of cell, etc, or you have to supply two Range objects, such as two cells Worksheets("Sheet1").Range(Worksheets("Sheet1").Cells(1,1), Worksheets("Sheet1").Cells(2,2)), which defines area starting with upper-left corner in first parameter and lower right in second parameter.
ActiveCell.Row and ActiveCell.Column returns you some Integer value representing number of row and column, i.e. if you point cell B4, ActiveCell.Row would return 4, and ActiveCell.Column gonna return 2. An Range() property need as an argument whole adress for some range, i.e. Range("C6") or Range("G3:J8").
When you have your column as a number, you can use Cells() property for pointing first and last cell in your range, i.e. Range(Cells(2, 4), Cells(6, 8) would be the same range as Range("D2:H6").
Following this, one of the ways that you can do what you have described is:
Sub CommandButton1_Click()
Dim Rng As Range
Set Rng = Worksheets("Sheet1").Cells(ActiveCell.Row, ActiveCell.Column)
End Sub
Now you have under variable Rng an Range of the same coordinates as ActiveCell, but in Sheet1. You can pass some value into i.e Rng.Value = "Hello World", paste something with Rng.PasteSpecial xlPasteAll etc.
if you want the value from other sheet at the same location as activeCell, use this code,
Private Sub CommandButton1_Click()
valueFromOtherSheet = Sheets("Sheet2").Range(ActiveCell.Address)
MsgBox (valueFromOtherSheet)
End Sub
Like the others have said, it's just about knowing your variable types. This is another way you could achieve what you want
Sub CommandButton1_Click()
Dim Acell As Range
Set Acell = Worksheets("Sheet2").Range(ActiveCell.Address)
MsgBox "Value on ActiveSheet: " & ActiveCell.Value & vbNewLine & _
"Value on Sheet2: " & Acell.Value
End Sub
Thank you everyone for the help and clarification, In the end I was able to come up with some code that seems to do what I need it to.
Private Sub CommandButton1_Click()
Dim cabDate As Range
Dim searchCol As Integer
Dim newindex As Range
Set cabDate = WorksheetFunction.Index(Range("A1:O9999"), ActiveCell.Row, 2)
searchCol = ActiveCell.Column
Set newindex = WorksheetFunction.Index(Worksheets("Deadlines").Range("A1:O9999"), cabDate.Row, searchCol)
MsgBox (newindex)
End Sub
I wasn't aware about conflicting data types so thank you all for the assistance.

How to change range to run only when there information

I have an excel sheet where I am doing a VlookUP using VBA. The problem is that I extract information, and the amount is always different. I want to find a way to add to the code that will add information until there is no more information to add.
Here is the code that works but only for the cells I put in:
Sub vLook()
With ThisWorkbook.Worksheets("EODComponents").Range("f5:F200")
.Formula = "=VLOOKUP(C5,($H$5:$i$34),2,FALSE)"
.Value = .Value
End With
End Sub
You can set a lastRow:
Sub vLook()
Dim lastRow as Long
With ThisWorkbook.Worksheets("EODComponents")
lastRow = .Cells(.Rows.Count,6).End(xlUp).Row
With .Range("f5:F" & lastRow)
.Formula = "=VLOOKUP(C5,($H$5:$i$34),2,FALSE)"
.Value = .Value
End With
End With
End Sub
Maybe you can try to use a Do while-loop?
If you put the while statement right, this will continue until the statement becomes false, in your case; there is no more information to add.
You can use the Len()-function to check the length of the text/value inside a cell, when this is zero you can assume the cell is empty.
More information about this item can be found here.
Example:
Public Sub Something()
Dim i As Integer
i = 1
Do While (Len(Cells(i, 1).Text) > 0)
i = i + 1
Loop
MsgBox "The next row of column 'A' is empty: A" & i
End Sub
Hope this helps.

Excel VBA running a function on every cell in a row with a dynamic range

I would like to run a function called ToNum on every cell in a row with a value that will convert a cell contents to a string. Here is my code below but I am getting a compile error, can anyone assist and let me know what I am doing wrong?
Sub ConvRows()
Dim rng As Range
Dim cell As Variant
Set rng = Range("A8:A" & Range("A" & Rows.Count).End(xlUp).Row).Select
For Each cell In rng
cell.Value = ToNum(cell.Value)
Next
End Sub
Function ToNum(X As Variant) As String
Dim A As String
A = Trim(Str(X))
ToNum = A
End Function
I would add this as a comment, but I don't have enough reputation points to comment. To avoid the type mismatch error on cells that already contain a string, you could put your call to ToNum in an if statement in your subroutine like this:
If IsNumeric(cell.Value) Then
cell.Value = ToNum(cell.Value)
End If
That should keep the subroutine from touching cells that are already strings.
Consider:
Function ToNum(X As Variant) As String
Dim A As String
A = Trim(Str(X))
ToNum = "'" & A
End Function