Excel use cell value as range in VBA - vba

I have an excel file. There is a changable row quantity for column A for every time and that's why I need to make dynamic formula. For example;
I want to write "=LEN(B1)" formula on B1. And when make double click on right down corner of the cell, it's going to the end of until when column A values ends. That's why, before all this process, I wrote "=COUNT(A:A)" on cell C1.
In my VBA, I want to write;
Dim TEMP As String
TEMP = Range("C1").Value
Range("B1").Select
ActiveCell.FormulaR1C1="=+LEN(RC[-1])"
Selection.AutoFill Destination:=Range("B1:TEMP")
But there is something wrong in this process. As a result, I just want to use a cell value in my VBA as a range or string or number.
Thanks for your support.

Two notes:
It's best practice to always qualify your objects (workbooks, worksheets, ranges, etc.) beforehand
When you use R1C1 notation, you can just write the formula directly to the range (with no need for AutoFill or FillDown)
Try this:
Dim ws as Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1") 'edit for your sheet name
Dim lRow as Long
lRow = ws.Range("A" & ws.Rows.count).End(xlup).Row
ws.Range("B1:B" & lRow).FormulaR1C1 = "=Len(RC[-1])"
And just as a side note worth mentioning the way you wrote Range("B1:TEMP") is not proper syntax. Correct syntax would be Range("B1:B" & TEMP), which, of course, would only work if TEMP was indeed a numerical value :)

Related

How to highlight a cell based on another cells value VBA?

This question has been asked before but I went about doing it another way. I am trying to highlight a cell if it is greater than the value of another cell.
Here is my code:
Sub Error_Search()
Dim Summary As Worksheet
Dim lr As Long
Set Summary = Worksheets("Summary")
lr = Cells(Rows.Count, 20).End(xlUp).Row
With Summary
For i = lr To 3 Step -1
If Range("L" & i).Value > Range("$Q$2:$R$3").Value Then Range("L" & i).Font.Color = -16776961
Next i
End With
End Sub
Range("$Q$2:$R$3") is a merged cell and it is the cell I want to compare the cell I want to highlight to.
I keep getting a mismatch error.
Any help would be greatly appreciated.
Thanks,
G
As mentioned in the comments, the problem is that a multiple-cells Range doesn't have a single Value, even if the cells are merged: Range.Value yields a 2D variant array whenever more than a single cell is involved. So you can fix the bug by only referring to the top-left cell of the merged range instead.
That said...
You don't need any VBA code to do this; conditional formatting handles it quite neatly.
=$C4>$M$3
Note the $ dollar signs: $M$3 would be your merged cell (only the leftmost cell matters), and $C4 is just the first cell you're defining the conditional format into; leaving the row non-absolute (i.e. no $ on the row number) allows you to apply the format to an entire range of cells by specifying the Applies to range:
Note that the format formula is the same regardless of whether we're looking at $M$3 or $M$3:$N$3 merged cells.
Conditional formats will perform much better than any VBA code you can write.

Index Match 2 criteria in VBA

I have a macro I'm trying to create to map a bunch of old values to new values. At one point I need to do a match on 2 columns and get the value from a third column. In normal excel I would run the formula below, but as it is a Formula Array (have to CTRL+SHIFT+ENTER to run) I'm not quite sure how to get this to work in VBA
=INDEX($D:$D,MATCH(1,(E2=$A:$A)*(F2=$B:$B),0))
Any help appreciated
Have you tried?
Cell.FormulaArray()
It should work with normal notation, although it is intended for R1C1
There are essentially three ways to evaluate an array formula to a result within VBA.
The first is 'square bracket' evaluation. This processes a formula just as if it is on the worksheet.
Dim result As Variant
result = [INDEX('Sheet1'!D:D,MATCH(1,(E2='Sheet1'!A:A)*(F2='Sheet1'!B:B),0))]
Debug.Print result
Care must be given to explicitly show worksheet parentage. In the above, the full columns have been given a parent worksheet but the individual cells have not. The individual cells will default to the ActiveSheet property which may or may not even be in the same workbook. Define all cell references explicitly!
The second method is with Application.Evaluate method. This allows more freedom with the formulas using string construction.
Dim result As Variant, wsn As String
wsn = Worksheets("Sheet1").Name
result = Application.Evaluate("INDEX('" & wsn & "'!D:D, " & _
"MATCH(1, (E2='" & wsn & "'!A:A)*(F2='" & wsn & "'!B:B),0))")
Debug.Print result
Again, only the full column references have been given parent worksheet references. This should be fixed before run-time use. This method is better for array formulas because you can use string construction to cut the full column references down to the rows in the Worksheet.UsedRange property.
As mentioned, the third method involves writing the formula to a worksheet cell using the Range.FormulaArray property and retrieving the answer from the cell.

“Unable to get the VLookup property of the WorksheetFunction Class” vlookup in a loop

I'll just say right off the bat that I'm a newb in coding overall. I've learned a lot along the way creating various things at work for myself and I'm learning all the time.
The problem I have right now is with a loop using application.vlookup(...). I've done a lot of searching around but I gave up because I couldn't get anything to work. I've removed the .WorksheetFunction part from the original code because apparently it doesn't change anything but at least it doesn't give VBA errors when a value is not found and acts similar to the normal function (gives #N/A).
So in the below code I have my data in column A which I need to convert using vlookup on a Query in another worksheet (and put that in the same sheet as the data, in column C).
Sub vlookup()
Dim wsdata As Worksheet
Dim lr As Long
Dim rng As Range
Set wsdata = ThisWorkbook.Worksheets("Data")
wsdata.Columns("C").Delete
wsdata.Range("D1") = "Correct number"
lr = wsdata.Cells(Rows.Count, "A").End(xlUp).Row
Set rng = wsdata.Range("A1:D" & lr)
Dim lrQuery As Long, iNr As Long
Dim wsQuery As Worksheet
Dim LookUpRange As Range
Set wsQuery = ThisWorkbook.Sheets("IDMquery")
lrQuery = wsQuery.Cells(Rows.Count, "A").End(xlUp).Row
Set LookUpRange = wsQuery.Range("D:F")
For iNr = 2 To lr
wsdata.Cells(iNr, 4).Value = Application.VLookup(wsdata.Cells(iNr, 1).Value, LookUpRange, 3, 0)
Next iNr
End Sub
I have to add that there are some issues with the formatting (or whatever they are), because the original data is external. Eg. for "17935" VarType would give 8 (string) instead of a numeric type.
In the spreadsheet it's easy to fix it with the double unary and the following formula works correctly:
=VLOOKUP(--A2,IDMquery!D:F,3,false)
Of course I could use a helper column and just use that, which might be an option if I can't do it any other way, but I would prefer strictly within VBA.
Do you guys know if this is fixable?
Cheers!
EDIT: Btw, I also changed the formatting of column A to "0" in VBA but it doesn't actually want to change these values to numeric, not sure why.

How to move to next blank cell?

I have data on multiple sheets in a workbook that I want copied all to one sheet in that same workbook. When I run the macro, I would like it to start by deleting the current data in the "iPage Data Export" sheet and then replacing it with data from the other sheets.
I want the process to occur one column at a time since I may not bring over everything. Right now I am trying to learn how to do just one column.
I was able to get it to copy all of the contents of a column from one sheet, but when it moves to the next sheet, it overwrites the existing data. In the end, I only get one sheets worth of data copied.
Here are my 4 problems:
How do I make it clear the data on this sheet before running the routine?
How can I make it start each copy function at the bottom of that row (i.e. after the last cell with a value)? I have tried many of the suggestions on this and other boards without success. I will admit I am not very experienced in this.
How can I make it copy to a particular column (currently it just seems to default to A.
How can I concatenate multiple columns during the paste function? I.e. what if I want it to insert: A2&", "B2 instead of just A2
Sub CombineData()
Dim Sht As Worksheet
For Each Sht In ActiveWorkbook.Worksheets
If Sht.Name <> "iPage Data Export" Then
Sht.Select
Range("C:C").Copy
Sheets("iPage Data Export").Select
ActiveSheet.Paste
Else
End If
Next Sht
End Sub
How do I make it clear the data on this sheet before running the routine?
Sht.Cells.ClearContents
How can I make it start each copy function at the bottom of that row (i.e. after the last cell with a value)? I have tried many of the suggestions on this and other boards without success. I will admit I am not very experienced in this.
Range("C" & Rows.Count).End(xlUp).Offset(1, 0)
In detail:
Rows.Count will return the number of rows in the sheet, so in the legacy style *.xls workbooks this would return the number 65,536. Therefore "C" & Rows.Count is the same as C65536
Range("C" & Rows.Count).End(xlUp) is the same as going to C65536 and pressing Ctrl + ↑ - The command End(xlDirection) tells the program to go the last cell in that range. In this case, we would end up at the last cell containing data in column C.
.Offset(1, 0) means that we want to return the range offset by an amount of rows and/or columns. VBA uses RC (Rows Columns) references, so whenever you see something like the Offset() function with two numbers being passed as the arguments, it usually relates to the row, and the column, in that order. In this case, we want the cell that is one row below the last cell we referenced.
All-in-all the phrase Range("C" & Rows.Count).End(xlUp).Offset(1, 0) means go to the last cell in column C, go up until we hit the last cell with data, and then return the cell below that - which will be the next empty cell.
How can I make it copy to a particular column (currently it just seems to default to A.
Range("C:C").Copy Destination:=Sheets("iPage Data Export").Range("A:A")
You can pass the Destination argument in the same line and actually bypass the clipboard (faster and cleaner)
How can I concatenate multiple columns during the paste function? I.e. what if I want it to insert: A2&", "B2 instead of just A2
Lets say you wanted to reference column A, B, and F - just use:
Range("A1, B1, F1").EntireColumn
To summarise, you could streamline your existing code to something like (untested):
Sub CombineData()
Dim Sht As Worksheet
For Each Sht In ActiveWorkbook.Worksheets
If Sht.Name <> "iPage Data Export" Then
Sht.Range("C1:C" & Cells(Sht.Rows.Count, 3).End(xlUp).Row).Copy Destination:=Sheets("iPage Data Export").Range("A:A")
End If
Next
End Sub
This should do for the copying:
Sub CombineData()
Dim sheet As Worksheet
For Each sheet In Worksheets
If (sheet.Name <> "iPage Data Export") Then
sheet.Select
Range("A1", ActiveCell.SpecialCells(xlLastCell)).Select
Selection.Copy
Worksheets("iPage Data Export").Activate
Cells(1, ActiveCell.SpecialCells(xlCellTypeLastCell).Column + 1).Select
ActiveSheet.Paste
End If
Next
End Sub
For the concatenation you need to be more specific - but I guess you should open a new question with a clearer focus if you need specific help on that.

Find duplicate and copy adjacent cell into

I need some help getting some direction on this task.
I have two spreadsheets dumps with large quantities of information. I need to combine them into one organized sheet.
Spreadsheet A has path to the file (via hard drive), with loads of additional info needed to be retained.
Spreadsheet B had path to the file (via hard drive), and for those in the content management system, the path in the CMS.
I would like to copy spreadsheet B into worksheet 2 in spreadsheet A, then run a macro that will search for matching values (path to file via hard drive), and where the same, copy the adjacent value of worksheet B (path in CMS) and copy that in the appropriate cell in spreadsheet A.
I have a vlookup function that does exactly what I need it to do, but how do I go about and put it in a macro to run?
=VLOOKUP(H1,A:B,2,FALSE)
How would I put this into a macro that returns the value, not just puts the formula in the cell?
Sub PCMSLookup()
Dim LastRow As Long
LastRow = Range("B" & Cells.Rows.Count).End(xlUp).Row
Range("J15:J" & LastRow).Formula = "=VLOOKUP(B15,'PCMS-dump'!A:B,2,FALSE)"
End Sub
The quickest way to put the value into the cells is to block in the formula then revert the formula to the returned value.
Sub PCMSLookup()
Dim LastRow As Long
with sheets("Sheet1") '<-set this worksheet reference properly
LastRow = .Range("B" & Cells.Rows.Count).End(xlUp).Row
with .Range("J15:J" & LastRow)
.Formula = "=VLOOKUP(B15, 'PCMS-dump'!A:B, 2, FALSE)"
.cells = .value2
end with
end with
End Sub
Note that when you are within a With/End With grouping, all of the range and cell references are prefixed with a period (e.g. . or full stop). This shows that they are children of closest With/End With.