Referencing a Worksheet in a Formula That's Always Changing in VBA - vba

I am trying to write a macro that copies data from another worksheet. I am having troubles on how to properly input the worksheet name in a formula. The Summary worksheet is the destination and the 5th worksheet, which will change daily (and is in format x.xx_1), is the source. Here's my code:
Sub steadf()
Dim SN As String
SN = InputBox("Enter Tab Date - 2.24, 10.24, etc.")
Worksheets(5).Name = SN & "_1"
Sheets("Summary").Select
Range("D24").Select
ActiveCell.Offset(0, 3).Formula = "=SN" & "_1" & "!" & "Cost"
End Sub
When I run this, the formula in G24 is
=SN_1!Cost
The formula I'm looking to use is ='2.24_1'!Cost. I would appreciate any help. Thanks in advance.

Try this:
Formula = "='" & SN & "'!Cost"

Related

VBA Sumifs to paste result as values

Would like to know how to code properly a SUMIFS formula and paste the results as value only.
Is it also possible to just have the formula loop only on blank cells? I tried running the code and it seems that is pastes the formula for all cells.
I've attached a sample code which I only got from other forums for reference. Would really appreciate your help guys!
Option Explicit
Sub SumGroups()
Dim lastCode As Long, lastFiltCode As Long
'Determine Last Row in Column O (Unfiltered Codes)
With Worksheets("Database")
lastCode = .Range("O" & .Rows.Count).End(xlUp).Row
End With
With Worksheets("Sheet3")
'Determine last Row in Column A (Filtered Codes)
lastFiltCode = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("B2:K" & lastFiltCode).Formula = _
"=SUMIFS(Database!$M$2:$M$" & lastCode & ",Database!$O$2:$O$" & lastCode & ",$A2,Database!$I$2:$I$" & lastCode & ",B$1)"
End With
End Sub
You just have to have the work occur in VBA:
cells(1,1).value = Application.SumIfs(Range(Cells(1,1),Cells(10,1)),Range(Cells(1,2),Cells(10,2)), "<0")
Or, you can do this AFTER you have shown the formulas, so the value of the formula is pasted in place of the formula:
cells(1,1).value = cells(1,1).value
Edit1:
To point out why your code is entering the formula, by using .Formula = "", you are telling the system to display within the defined range that exact information. These each enter whatever is within the quotations to the cell:
cells(1,1).value = "Cat"
cells(1,1).formula = "=A1+B1"
cells(1,1).formula = "=A" & i & "+B" & i 'where i is a variable

Formatting a Formula in a String VBA

I have a script that needs to place a formula into a cell but I'm getting a 1004 error from the first part I am sure I formatted something wrong. I had difficulty with the " marks in the string but got those worked out so I'm figuring I'm missing something else. The cells are also unprotected.
Worksheets(CurSheet + 1).Range("D" & Y).Value = "=IF(D52=1,0,IF(C52=" & """Saturday""" & ",0,'" & CurSheet & "!C" & Y & "))"
This is the section that gives the error. If it is removed code works.
"=IF(D52=1,0,IF(C52="
I am not sure what I am doing wrong with this part.
It looks like you're using CurSheet as a sheet index number and as a sheet name.
The index number just returns the relative position of the sheet in the workbook while the name is what you see on the sheet tab (there's also the CodeName but I won't go into that here).
Although I don't fully understand what you're after this code will place a formula on the sheet identified with the sheet index number, so if CurSheet= 1(+1) it will place the formula on the second sheet.
The formula itself will reference the name of the sheet that is before the sheet that the formula appears on (so if the formula is on the second sheet, the formula will reference the first sheet).
Sub Test()
Dim Y As Long
Dim CurSheet As Long
Y = 1
CurSheet = 1
Worksheets(CurSheet + 1).Range("D" & Y).Formula = _
"=IF(D52=1,0,IF(C52=" & """Saturday""" & ",0,'" & Worksheets(CurSheet).Name & "'!C" & Y & "))"
End Sub
Hope I made that clear enough. :)
You need to declare that you are inputting a formula, not a value:
Change:
Worksheets(CurSheet + 1).Range("D" & Y).Value
To:
Worksheets(CurSheet + 1).Range("D" & Y).Formula

Inserting a formula containing variable into a cell using a macro

I have a vba macro that copies the current sheet and renames it with the current date that works fine, now I want it to put a formula in cell B22, the formula that I want is:
Current Sheet Previous Sheet
='08 May 2013'!B18 - '01-04-2013'!B18
I have been trying to get this code to work, but it is putting it in as a string not a formula
i.e. = ('[08 May 2013 !R2C18] - [ 12 May 2013 !R2C18])
Dim sheet_name As String
Dim activeSheet_name As String
Dim shtName As Integer
Dim activeShtName As Integer
shtName = Sheets.Count - 1
activeShtName = Sheets.Count
sheet_name = Sheets(shtName).Name
activeSheet_name = Sheets(activeShtName).Name
Sheets(activeSheet_name).Select
Range("B22").Select
ActiveCell.Formula = " = ('[" & sheet_name & " !R2C18] - [ " & activeSheet_name & " !R2C18])"
Any help would be appreciated
Your formula is wrong. Try it in Excel first, then copy the text of the formula and compare to the text that your last line of code above is producing. Change your VBA code to this:
ActiveCell.FormulaR1C1 = "='" & sheet_name & "'!R18C2-'" & activeSheet_name & "'!R18C2"
Note the use of FormulaR1C1. Basically you need to surround the sheet names with single quotes.

Excel macro to concatenate one row at a time to end of file

I need an Excel macro to join seven columns of data on each row until the end of the data is reached. For example if I have a formula like this:
=A1&B1&C1&D1&E1&F1&G1
How can I write the macro so that it increments for every row to the end of the file in a sequence like this?
=A1&B1&C1&D1&E1&F1&G1
=A2&B2&C2&D2&E2&F2&G2
=A3&B3&C3&D3&E3&F3&G3
With so many answers, the main focus on what assylias and I were highlighting has gone to waste :)
However, if you still want a VBA answer. Use this method. This is much faster than Looping or an Autofill.
Option Explicit
Sub Sample()
Dim LastRow As Long
Dim Ws As Worksheet
Set Ws = Sheets("Sheet1")
LastRow = Ws.Range("A" & Ws.Rows.Count).End(xlUp).Row
'~~> If your range doesn't have a header
Ws.Range("H1:H" & LastRow).Formula = "=A1&B1&C1&D1&E1&F1&G1"
'~~> If it does then
Ws.Range("H2:H" & LastRow).Formula = "=A2&B2&C2&D2&E2&F2&G2"
End Sub
If you have 1000's of rows then you might want to switch off Screenupdating and change Calculation to Manual before you run the code and then reset them at the end of the code.
I think the easiest way to do this would be to just fill down as assylias says but if you want to use VBA:
Selection.AutoFill Destination:=Range("Your Fill Range"), Type:=xlFillDefault
Should copy across the other rows.
I agree 100% with the comments and the other answers, why do you need VBA to do this, but just to answer your original question, this is how I would accomplish it:
Sub FillAllWithFormula()
Dim i As Variant
Dim wsht As Worksheet
'If you are using this for a specific Worksheet use the following
Set wsht = ThisWorkbook.Worksheets(yourWorksheetName)
'or if you are always using this for the active sheet use the following
Set wsht = ActiveSheet
For i = 1 To wsht.Rows.Count
'Replace "X" with the column letter you want your formula to appear in
wsht.Range("X" & i).Formula = "=A" & i & "&B" & i & "&C" & i & "&D" & i & "&E" & i & "&F" & i & "&G" & i
Next
Set wsht = Nothing
End Sub

How do I get a range's address including the worksheet name, but not the workbook name, in Excel VBA?

If I have a Range object--for example, let's say it refers to cell A1 on a worksheet called Book1. So I know that calling Address() will get me a simple local reference: $A$1. I know it can also be called as Address(External:=True) to get a reference including the workbook name and worksheet name: [Book1]Sheet1!$A$1.
What I want is to get an address including the sheet name, but not the book name. I really don't want to call Address(External:=True) and try to strip out the workbook name myself with string functions. Is there any call I can make on the range to get Sheet1!$A$1?
Only way I can think of is to concatenate the worksheet name with the cell reference, as follows:
Dim cell As Range
Dim cellAddress As String
Set cell = ThisWorkbook.Worksheets(1).Cells(1, 1)
cellAddress = cell.Parent.Name & "!" & cell.Address(External:=False)
EDIT:
Modify last line to :
cellAddress = "'" & cell.Parent.Name & "'!" & cell.Address(External:=False)
if you want it to work even if there are spaces or other funny characters in the sheet name.
Split(cell.address(External:=True), "]")(1)
Ben is right. I also can't think of any way to do this. I'd suggest either the method Ben recommends, or the following to strip the Workbook name off.
Dim cell As Range
Dim address As String
Set cell = Worksheets(1).Cells.Range("A1")
address = cell.address(External:=True)
address = Right(address, Len(address) - InStr(1, address, "]"))
The Address() worksheet function does exactly that. As it's not available through Application.WorksheetFunction, I came up with a solution using the Evaluate() method.
This solution let Excel deals with spaces and other funny characters in the sheet name, which is a nice advantage over the previous answers.
Example:
Evaluate("ADDRESS(" & rng.Row & "," & rng.Column & ",1,1,""" & _
rng.Worksheet.Name & """)")
returns exactly "Sheet1!$A$1", with a Range object named rng referring the A1 cell in the Sheet1 worksheet.
This solution returns only the address of the first cell of a range, not the address of the whole range ("Sheet1!$A$1" vs "Sheet1!$A$1:$B$2"). So I use it in a custom function:
Public Function AddressEx(rng As Range) As String
Dim strTmp As String
strTmp = Evaluate("ADDRESS(" & rng.Row & "," & _
rng.Column & ",1,1,""" & rng.Worksheet.Name & """)")
If (rng.Count > 1) Then
strTmp = strTmp & ":" & rng.Cells(rng.Count) _
.Address(RowAbsolute:=True, ColumnAbsolute:=True)
End If
AddressEx = strTmp
End Function
The full documentation of the Address() worksheet function is available on the Office website: https://support.office.com/en-us/article/ADDRESS-function-D0C26C0D-3991-446B-8DE4-AB46431D4F89
I found the following worked for me in a user defined function I created. I concatenated the cell range reference and worksheet name as a string and then used in an Evaluate statement (I was using Evaluate on Sumproduct).
For example:
Function SumRange(RangeName as range)
Dim strCellRef, strSheetName, strRngName As String
strCellRef = RangeName.Address
strSheetName = RangeName.Worksheet.Name & "!"
strRngName = strSheetName & strCellRef
Then refer to strRngName in the rest of your code.
You may need to write code that handles a range with multiple areas, which this does:
Public Function GetAddressWithSheetname(Range As Range, Optional blnBuildAddressForNamedRangeValue As Boolean = False) As String
Const Seperator As String = ","
Dim WorksheetName As String
Dim TheAddress As String
Dim Areas As Areas
Dim Area As Range
WorksheetName = "'" & Range.Worksheet.Name & "'"
For Each Area In Range.Areas
' ='Sheet 1'!$H$8:$H$15,'Sheet 1'!$C$12:$J$12
TheAddress = TheAddress & WorksheetName & "!" & Area.Address(External:=False) & Seperator
Next Area
GetAddressWithSheetname = Left(TheAddress, Len(TheAddress) - Len(Seperator))
If blnBuildAddressForNamedRangeValue Then
GetAddressWithSheetname = "=" & GetAddressWithSheetname
End If
End Function
rngYourRange.Address(,,,TRUE)
Shows External Address, Full Address
The best way I found to do this is to use the following code:
Dim SelectedCell As String
'This message Box allows you to select any cell on any sheet and it will return it in the format of =worksheetname!$A$X" where X is any number.
SelectedCell = Application.InputBox("Select a Cell on ANY sheet in your workbook", "Bookmark", Type:=8).Address(External:=True)
SelectedCell = "=" & "'" & Right(SelectedCell, Len(SelectedCell) - Len("[" & ActiveWorkbook.Name & "]") - 1)
'Be sure to modify Sheet1.Cells(1,1) with the Sheet and cell you want to use as the destination. I'd recommend using the Sheets VBA name.
Sheet1.Cells(1, 1).Value = SelectedCell
How it works;
By Clicking on the desired cell when the message box appears. The string from "Address(External:=True)" (i.e ['[Code Sheet.xlsb]Settings'!$A$1) is then modified to remove the full name of the worksheet([Code Sheet.xlsb]).
Using the previous example it does this by taking the "Len" of the full length of;
[Code Sheet.xlsb]Settings'!$A$1 and subtracts it with the Len of ([Code Sheet.xlsb] -1). leaving you with Settings'!$A$1.
SelectedCell = "=" & "'" & Right(SelectedCell, Len(SelectedCell) - Len("[" & ActiveWorkbook.Name & "]") - 1)
The Code then its and "='" to insure that it will be seen as a Formula (='Settings'!$A$1).
Im not sure if it is only on Excel on IOS but for some reason you will get an Error Code if you add the "='" in any other way than "=" & "'" as seen bellow.
SelectedCell = "=" & "'" & Right....
From here all you need is to make the program in the Sheet and cell you want your new formula in.
Sheet1.Cells(1, 1).Value = SelectedCell
By Opening a new Workbook the full Code above will work as is.
This Code is Especially useful as changing the name of the workbook or the name of the sheet that you are selecting from in the message box will not result in bugs later on.
Thanks Everyone in the Forum before today I was not aware that External=True was a thing, it will make my coding a lot easier. Hope this can also help someone some day.
Why not just return the worksheet name with
address = cell.Worksheet.Name
then you can concatenate the address back on like this
address = cell.Worksheet.Name & "!" & cell.Address
Dim rg As Range
Set rg = Range("A1:E10")
Dim i As Integer
For i = 1 To rg.Rows.Count
For j = 1 To rg.Columns.Count
rg.Cells(i, j).Value = rg.Cells(i, j).Address(False, False)
Next
Next
For confused old me a range
.Address(False, False, , True)
seems to give in format TheSheet!B4:K9
If it does not why the criteria .. avoid Str functons
will probably only take less a millisecond and use 153 already used electrons
about 0.3 Microsec
RaAdd=mid(RaAdd,instr(raadd,"]") +1)
or
'about 1.7 microsec
RaAdd= split(radd,"]")(1)
[edit on 2009-04-21]
As Micah pointed out, this only works when you have named that
particular range (hence .Name anyone?) Yeah, oops!
[/edit]
A little late to the party, I know, but in case anyone else catches this in a google search (as I just did), you could also try the following:
Dim cell as Range
Dim address as String
Set cell = Sheet1.Range("A1")
address = cell.Name
This should return the full address, something like "=Sheet1!$A$1".
Assuming you don't want the equal sign, you can strip it off with a Replace function:
address = Replace(address, "=", "")