Using VBA To Convert A Column of Formulas From Relative To Fixed Reference - vba

First off, apologies if this is a silly question. I'm new to VBA. I searched online for this answer but couldn't find it.
I'm trying to convert a long column of formulas from relative references to absolute cell references. Essentially, I would like VBA to go through the column, select a cell, "hit F4" and then move to the next cell.
I recorded this action in VBA and got the following:
ActiveCell.FormulaR1C1 = "='Worksheet'!R11C9"
Range("G5212").Select
My question is what in this command is the equivalent of hitting F4? I'm not good at reading VBA and I'm trying to understand this. And, of course, if I'm going about this completely the wrong way please let me know. Thank you.

Dim LastCell As Range
Set LastCell = Range("G" & Rows.Count).End(xlUp)
Range("G1", LastCell).Formula = Application.ConvertFormula _
(Formula:=Range("G1", LastCell).Formula, FromReferenceStyle:=xlA1, _
ToReferenceStyle:=xlA1, ToAbsolute:=xlAbsolute)
Change your column as needed. I assumed G based on question.

Related

Excel IF cell reference formula being changed when recorded in VBA

I have a macro that works fine. I'm adding a formula to it that describes the status of the workbook for someone else to review. When I record the macro of implementing the formula into the sheet, VBA records it using relative references even though I do not have the relative references button selected. The relative references do not point correctly so I need to fix it. I checked this post (adding a dynamic cell reference in vba) and am now thinking that I should adjust the formula with some VBA reference code but I'm not sure if what the post is using is suitable for me. Am I going in the right direction?
Excel Formula:
=IF(Selections!K2="","Not prepped","Prepped")
When recorded into VBA:
ActiveCell.FormulaR1C1 = _
"=IF(Selections!R[-41]C[-1]="""",""Not prepped"",""Prepped"")"
What I need in VBA code:
ActiveCell.FormulaR1C1 = _
=IF(Selections!K2="""",""Not prepped"",""Prepped"")
ok, then is this your answer:
dim rng as range
set rng = thisworkbook.sheets("Sheet1").range("L5")
rng.Formula = "=IF(Selections!K2="""",""Not prepped"",""Prepped"")"

sumifs to loop all sheets

I have been searching different forums and cant seem to find my answer.
I have rather basic VBA knowledge and build most of my code from bits online!
Regardless of cell references as I would be able to work these out at a later date.
Please can you let me how I would make a sumifs formula reference across multiple sheets.
This is being build into a template and there would be a different number of sheets with different names each time it is run so I would be not be able to reference the sheets.
sorry thats a bit vague
thanks in advanced
Thanks, so for anyone else who needs this, this is how it was done in full
my original formula was
"=SUMPRODUCT(SUMIF(INDIRECT(" '"&Invoices&"'!"&"A2006:A3005"),A3,INDIRECT("'"&Invoices&"'!"&"B2006:B3005")))"
this worked when putting straight into a cell but as you can see, when adding it to VBA it reads it as a comment. To fix this, every time you use a " you need to add extra " as shown bellow (apart form before the" = at the start and after the )" at the end of the formula)
*****'list all the sheet names in cell AI1 of the sheet summary*****
For i = 1 To Sheets.Count
Sheets("Summary").Range("AI1")(i, 1).Value = Sheets(i).Name
Next i
***'clear the first 3 entries in AI as i didnt need the first three sheet names***
Sheets("Summary").Select
Sheets("Summary").Range("AI1:AI3").Clear
***'select the first sheet name, which is in AI4 as we cleard the first 3 to the last used cell, e.g Ctrl.Shift.down***
Sheets("Summary").Activate
Sheets("summary").Range(ActiveSheet.Range("AI4"), ActiveSheet.Range("AI4").End(xlDown)).Select
***' Name the range invoices***
Selection.Name = "Invoices"
' ***Formula to do a sumIf looping all the shets in the named range Invoices***
Sheets("summary").Range("B3").Formula = "=SUMPRODUCT(SUMIF(INDIRECT(""'""&Invoices&""'!$A$2006:$A$3005""),$A3,INDIRECT(""'""&Invoices&""'!B$2006:B$3005"")))"

Inserting, searching, copying, pasting across 2 spreadsheets in Excel

I thought I'd be able to figure this out based off an analysis of similar code we had written for something else, but code isn't my forte.
Diving into VBA without guidance has proved to be too daunting for me to proceed.
Forgive my terminology if I use the wrong language, I'm happy to learn and be corrected.
This shouldn't be difficult for someone that knows what they're doing, I just don't at all.
I'm trying to create a macro enabled workbook that does the following:
Open "Data.csv" from a folder called "Data" in the same directory as the macro. We'll call this workbook A - wbA.
Insert a column on wbA after Column C titled "Group Image Name." This Column D is where we want data to end up.
Open "Groups.csv" from a folder called "Groups" in the same directory as the macro. We'll call this workbook B - wkB.
(This next part needs to be a loop that starts at C1 on wbA and proceeds down the column until the end of the spreadsheet)
Copy value from selected cell in Column C on wbA
Search Column C on wbB for copied value. When found, move selection over to corresponding cell in Column A. (If C2, then A2)
Copy contents of the column A value from wbB to column D cell on wbA that corresponds to the original starting point on wbA.
Basically in plain language: Search for Column C contents from wbA on Column C of wbB. When found, move to Column A of same cell # on wbB, copy contents, and paste into cell # of Column D on wbA that corresponds to cell # of starting point from Column C.
I hope that's clear; please feel free to ask for more details if necessary. Thanks for anyone's help in advance!
Here is my terrible code I'm working with at the moment:
Sub OpenDataAddGroupImageTitleColumn()
ChDir "C:\[RealCodeHasCorrectFilepath..]\Desktop\TEST"
Workbooks.Open Filename:="C:\[RealCodeHasCorrectFilepath..]\Desktop\TEST\DATA.csv"
Columns("D:D").Select
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Cells.Select
Cells.EntireColumn.AutoFit
Range("D1").Select
ActiveCell.FormulaR1C1 = "Group Image Title"
Range("C2").Select
'Variables for storing Row, Column Location, and Value here
Dim GROUPNAME As String
Dim RowLocationX As Long
Dim ColumnLocationZ As Integer
GROUPNAME = ActiveCell.Value
RowLocationX = ActiveCell.Row
ColumnLocationZ = ActiveCell.Column
Workbooks.Open Filename:="C:\[RealCodeHasCorrectFilepath..]\Desktop\GROUPS.csv"
Columns("C:C").Select
Selection.Find(What:="GROUPNAME", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
End Sub
The current snag I can't figure out after much googling is this: Is it possible to search for my variable GROUPNAME using the Find/Replace feature? Or should I be taking a different approach using something involving copying to clipboard?
The first problems that I see are:
1) You don't put functions in the middle of sub routines. If you want a function, you put it on its own as such:
Sub MySub()
'Do Stuff
x = myFunction()
debug.print x
End Sub
Function MyFunction() As String
'Do Stuff
MyFunction = "Test"
End Function
2) The code you have provided won't compile for reason 1 and also because you have ended the Sub with "End Function" instead of End Sub. Try running the code and you will get error messages. Then you can research the error message and try to fix it. Further, if you don't get error messages, you can step through the code to make sure it is working the way you intend it to.
3) The very first line isn't going to work. You need to use the ENTIRE path of the file, even if it is in the same folder as the file you currently have open. There are ways to get the directory of the file you currently have open (google will surely show you many of them), and you could just append the filename to the directory of the file you have open.
4) You want a loop, but you haven't put in any looping structions. Google "Excel VBA loop through cells" and you can find many examples to use.
5) I think the biggest issue that you are having is that you are overwhelmed because you are trying to do everything all at once. I would suggest solving one problem at a time and then putting the code together. For instance, you want to open two files. Start by writing code just to open one file. Then try to get a value out of the file into the open workbook. Then open another file. Then get data out of that file. Then test looping through cells in the current workbook and checking for desired criteria and pasting the results if they match. Then combine all of these things into coherent code.
Nobody writes efficient code the first time they try, so even if you end up with really long code that isn't efficient, you'll learn a lot and have something. Even experienced programmers can get stuck or write code that doesn't work the first or even tenth time. If you get stuck, ask a specific question about a specific error message or specific issue that you can't resolve.

Identifying and using Relative variable in excel VBA Macro?

Alright, so I have a spreadsheet, and I want to use this code (and more) but I'm getting problems. I want to take row A and Find the [-x] I should be using (see RC[StartColumn]) and autofill the rest. I then want to be able to repeat the steps for columns A-AF.
So essentially I want to perform the first calculation below, and the second one right next to that, and I want to be able to start it anywhere on the document. I then want to be able to copy that down each row for every column leading up to the first cell I chose.
Problem is I'm incredibly new to Macros, I put that together by observing my record macro results and playing around a little, but this is becoming too advanced for my current level and I want to finish this by today if possible. Could someone please show me the way, in a way that could teach me so I could do this on my own in the future?
Sub ConcatenateStep1()
Dim StartColumn As Integer
StartColumn = 1 - ActiveCell.Column
ActiveCell.FormulaR1C1 = _
"=IF(AND(RC14=R[1]C14),IF(OR(ISNUMBER(FIND(LOWER(RC[StartColumn]),LOWER(R[1]C[StartColumn]),1)),ISNUMBER(FIND(LOWER(R[1]C[StartColumn]),LOWER(RC[StartColumn]),1))),IF(LEN(RC[StartColumn])<LEN(R[1]C[StartColumn]),R[1]C[StartColumn],RC[StartColumn]),CONCATENATE(RC[StartColumn],"", "",R[1]C[StartColumn])),IF(AND(RC14<>R[1]C14,RC14<>R[-1]C14),RC[StartColumn],"" ""))"
Range("AK2").Select
Set SourceRange = Range("AK2")
Set fillRange = Range("AK2:AK22000")
SourceRange.AutoFill Destination:=fillRange
Range("AL2").Select
ActiveCell.FormulaR1C1 = _
"=IF(AND(RC14=R[1]C14,RC14<>R[-1]C14),IF(OR(R[1]C[-1]="" "",ISNUMBER(FIND(LOWER(RC[-1]),LOWER(R[1]C[-1]),1)),ISNUMBER(FIND(LOWER(R[1]C[-1]),LOWER(RC[-1]),1))),IF(LEN(RC[-1])<LEN(R[1]C[-1]),R[1]C[-1],RC[-1]),CONCATENATE(RC[-1],"", "",R[1]C[-1])),IF(AND(RC14<>R[1]C14,RC14<>R[-1]C14),RC[-1],"" ""))"
Set SourceRange = Range("AL2")
Set fillRange = Range("AL2:AL22000")
SourceRange.AutoFill Destination:=fillRange
Range("AL2").Select
End Sub
This is only a partial answer.
Are these incredibly long and complicated formulae the best way of achieving whatever you want to achieving?
There are two errors in the first formula that prevent it being accepted by Excel when the macro attempts to place it in a cell.
The formula is a long string containing StartColumn. But StartColumn is a variable. You need to replace every occurence of StartColumn with " & StartColumn & ".
Within a string each double quote required in the result must be replaced by two double quotes. Within CONCATENATE(RC[StartColumn],"", "",R[1]C[StartColumn]) the double quotes have not been doubled although those at the end of the formula have.
Excel will accept the following (which means it is syntactically correct) although I do not understand its purpose so it may be logically incorrect:
ActiveCell.FormulaR1C1 = _
"=IF(AND(RC14=R[1]C14),IF(OR(ISNUMBER(FIND(LOWER(RC[" & StartColumn & _
"]),LOWER(R[1]C[" & StartColumn & "]),1)),ISNUMBER(FIND(LOWER(R[1]C[" & _
StartColumn & "]),LOWER(RC[" & StartColumn & "]),1))),IF(LEN(RC[" & _
StartColumn & "])<LEN(R[1]C[" & StartColumn & "]),R[1]C[" & StartColumn & _
"],RC[" & StartColumn & "]),CONCATENATE(RC[" & StartColumn & _
"],"""", """",R[1]C[" & StartColumn & _
"])),IF(AND(RC14<>R[1]C14,RC14<>R[-1]C14),RC[" & StartColumn & "],"" ""))"
If I have parsed this formula correctly, CONCATENATE(RC[StartColumn],"", "",R[1]C[StartColumn]) has the same output as CONCATENATE(RC[StartColumn],R[1]C[StartColumn])
I agree with MP24, you must clarify your question before I or someone else can help you further. The Macro Recorder records syntactically correct VBA but it is not good VBA. It does not know your objective so records individual keyboard actions when a skilled programmer would combine them. It is almost never a good idea to use Select or to work with the ActiveCell but the Macro Recorder has no choice but to do so.
Part 2
Although Excel allowed the macro to place the first forumula, it later complained the formula contains a circular reference. Its gone midnight here, I will look at it tomorrow.
Part 3
Having looked at your first formula again, I believe I incorrectly parsed it last night. I now believe the concatenate function is correct. Also it appears that the circular reference depends on the location of the ActiveCell when the macro starts. I was able to clear this error by selecting a different start position.
My current attempt to parse your formula gives:
Outer: "=IF(X1,X2,X3)"
X1: AND(RC14=R[1]C14)
X2: IF(X4,X5,X6)
X3: IF(X7,RC[StartColumn],"" "")
X4: OR(X8,X9)
X5: IF(X10,R[1]C[StartColumn],RC[StartColumn])
X6: CONCATENATE(RC[StartColumn],"", "",R[1]C[StartColumn])
X7: AND(RC14<>R[1]C14,RC14<>R[-1]C14)
X8: ISNUMBER(X11)
X9: ISNUMBER(X12)
X10: LEN(RC[StartColumn])<LEN(R[1]C[StartColumn])
X11: FIND(LOWER(RC[StartColumn]),LOWER(R[1]C[StartColumn]),1)
X12: FIND(LOWER(R[1]C[StartColumn]),LOWER(RC[StartColumn]),1)
I have used macros to place formulae so they can later give changing results as the user enters values. Do you want changing results? If not, replacing this formula with VBA would almost certainly give more understandable and more maintainable code.
I do not approve of formulae like this. I am aware that many people use complex formulae successfully and are pleased with the results. However, I have spent too much of my life picking up the pieces left by over clever people who have moved on. How long does it take to get a formula like this correct? How long does it take to amend when six or twelve months later a slightly different result is required? Too often, in my experience, the person who has to amend it six or twelve months later is not the original author. With VBA the author can leave comments saying what the code is doing but with formulae the author cannot. Over clever authors don't always leave the comments they should but at least VBA code is usually easier to decode than a complex formula.

Using a function to return a value in VBA without using the worksheet

Good afternoon One and All,
I am relatively new to VBA and I am trying to use the Worksheet function, specifically the index function to look up information in the code and bring back a value. I would love to do this without having to assign it to a cell in the worksheet using R1C1. Is there a way to do Vlookups, or Indexex without having to make assignments in the worksheet?
The examples below works as an equation placed within the sheet, but I'd like to get the same answer without having to use the sheet.
The first formula looks up a Batch number
The second formula is finding the name of the first ingredient in the batch, based on the SKU in the worksheet.
ActiveCell.FormulaR1C1 = _
"=VLOOKUP(RC[-1],'U:\Files\Maintenance File.xls'!SKUinfo,16,FALSE)"
ActiveCell.FormulaR1C1 = _
"=INDEX('U:\Files\[Recipe File.xlsx]Fresh 2800'!Fresh2800,2,6)*(INDEX(SchedInfo,MATCH(RC[-3],SKULookup,0),6))"
Any help would be appreciated, and thank you for all your help in advance.
The answer to this Microsoft forum post describes what you want. Use the Application object:
ans = Application.VLookup(arg1, MyRange, arg3, arg4)