Looping Syntax within Formula - excel

In my macro, I want to loop within formulas:
Range("D4").Formula = "=Inputs!D8
transforms successfully to:
For i = 1 To 5
Range("D4").Formula = "=Inputs!D" & i + 7
I want to do the same for the code below:
Range("G4").Formula = "=IF($C4<=Inputs!$E$8+Portfolio_Duration-1,SUM($H4:$DC4),"""")"
I tried
For i = 1 To 5
Range("G4").Formula = "=IF($C4<=Inputs!$E$" & i + 7+Portfolio_Duration-1,SUM($H4:$DC4),"""")"
But I am getting a compile error:
Expected: end of statement.
Could you please assist?
Thanks!

Try this out,
Range("G4").Formula = "=IF($C4<=Inputs!$E$" & i + 7 + Portfolio_Duration - 1 & ",SUM($H4:$DC4),"""")"
You are missing a " and a &

Related

ExcelScript: getNumberFormat from column A to C

I need to get the NumberFormat from an excel file (appr. 3000 lines) and I wrote a simple Script which copy it from column A to column C each row by row. I tried to use this script with Power Automate after 10 minutes.
I already set the timeout on 60 minutes, but it seems that my tenant configuration abort it always after exactly 10 minutes.
Here is my script:
function main(workbook: ExcelScript.Workbook) {
let sheet = workbook.getWorksheets()[0]
let range = sheet.getUsedRange(true);
let rows = range.getUsedRange(true).getRowCount();
let cols = range.getUsedRange(true).getColumnCount();
for (let row = 2; row <= rows; row++) {
sheet.getRange("C" + row).setValue(sheet.getRange("A" + row).getNumberFormat())
}
}
Is there an easier way to copy the NumberFormat from one column to another and does anybody know a better way?
Please make sure when you ask these questions to put the Office-Scripts tag since this is Office Scripts. You don't need to loop to achieve this. You can use getNumberFormats() like in the code below.
function main(workbook: ExcelScript.Workbook) {
let sheet = workbook.getWorksheets()[0];
let rowCount = sheet.getUsedRange(true).getRowCount();
let numFormats = sheet.getRange("A1:A" + rowCount).getNumberFormats();
let newRng = sheet.getRange("C1:C" + numFormats.length).setValues(numFormats);
}
EDIT 4/23/21
If you just want to get the indent levels, then you could just insert this formula in column C rather than getting the number formats.
=IFERROR(LET(indentLevel,FIND("[",FILTER(A:A,A:A<>""),1),SWITCH(indentLevel,4,1,6,2,8,3,10,4,12,5)),"Other Formula Here")
Here is the Office Scripts
function main(workbook: ExcelScript.Workbook) {
let sheet = workbook.getWorksheet("Sheet1");
sheet.getRange("C1")
.setFormulaLocal("=IFERROR(LET(indentLevel,FIND(\"[\",FILTER(A:A,A:A<>\"\"),1),SWITCH(indentLevel,4,1,6,2,8,3,10,4,12,5)),\"Other Formula Here\")");
}
Here is my VBA code where I use a for loop:
Sub GetHierachyParents()
Set appExcel = holeAnwendung("Excel.Application")
Set wbkExcel = appExcel.Workbooks.Open("C:\impport.xlsx")
Set wksExcel = wbkExcel.Sheets("Hierachy")
countRows = wksExcel.Range("A1").End(xlDown).Row
For i = 2 To countRows
Node = 0
If (Len(wksExcel.Range("A" & i).NumberFormat) - Len(Replace(wksExcel.Range("A" & i).NumberFormat, "[-]", "")) > 0) Then
IndentLevel = (Len(wksExcel.Range("A" & i).NumberFormat) - Len(Replace(wksExcel.Range("A" & i).NumberFormat, " ", "")) - 1) / 2
Node = -1
Else
IndentLevel = (Len(wksExcel.Range("A" & i).NumberFormat) - Len(Replace(wksExcel.Range("A" & i).NumberFormat, " ", "")) - 5) / 2
Node = 0
End If
sql = "INSERT INTO impTemp0 (F1, F2, F3, F4) VALUES ('" & wksExcel.Range("A" & i) & "', '" & Replace(wksExcel.Range("B" & i), "'", "") & "', " & IndentLevel & ", " & Node & ")"
CurrentDb.Execute sql
Next i
CurrentDb.Execute "UPDATE [impTemp0] SET Parent = DMAX('id','[impTemp0]','[impTemp0].id<' & [impTemp0].id & ' AND [impTemp0].Level=' & [impTemp0].Level-1 & '')"
End Sub
And here is an example for the first 8 rows:
" [-] "#
" [-] "#
" [-] "#
" [-] "#
" [-] "#
" "#

Formula inside a variable

I have the following question, is it posible to insert a formula inside a variable in VBA Excel to use this variable after?
For example:
MinO = "=MIN(" & .Cells(3, 7 + NumSheet).Address(False, False) & ":" & .Cells(3, 9 + NumSheet).Address(False, False) & ")"
For N = 1 To NumSheet + 1
.Cells(4, 5 + N).Value = 80 * ((.Cells(3, 8 + NumSheet).Value - .Cells(3, 5 + N).Value) / (.Cells(3, 8 + NumSheet).Value - MinO))
.Cells(4, 5 + N).Font.Bold = True
Next N
So MinO is a variable with a formula inside, I know in Range().Formula it works but how can I make it work using a variable?
I know there is also the Application.WorksheetFunction.Min but I want to see if it's posible doing it the other way as WorksheetFunction sometimes give me some errors.
Thank you so much for your answers!
You can do this, but therefore you need the Evaluate() function. (The URL refers to the official documentation of that function)
So, in your case, you might use: (seems not to be completely correct, so I'll put it in comment)
' .Cells(4, 5 + N).Value = 80 * ((.Cells(3, 8 + NumSheet).Value - .Cells(3, 5 + N).Value) / (.Cells(3, 8 + NumSheet).Value - Evaluate(MinO)))
As mentioned in below comments, the following seems to be the correct approach:
MinO = Evaluate("=MIN(" & .Cells(3, 7 + NumSheet).Address(False, False) & ":" & .Cells(3, 9 + NumSheet).Address(False, False) & ")")
Usually when I work with formulas from excel i write them in cell (check that everything works) and then in VBA immediate window (CTRL+G) I type
? Activecell.Formula
or
? Activecell.FormulaR1C1
And it displays formula that you need... That is good start then you start changing parts to reflect your desired variable changes.
Remember that this output is string and in code needs to start and end with 1x", when you want to add string in formula you need to add "" also sometimes you need to add """" and """ for strings in string... :)
I don't think this will work, as it is basically just a text string. I believe that you try to look into why the Application.WorksheetFunction is giving errors instead, or creating your own function if you have some special cases that the worksheet function cannot handle.

Excel VBA: Paste formula in While loop

I have developed the following While loop and want not only add the data but also insert a formula into the mix. The formula is added but does not increment by row. See R4. I could write a separate While loop or For to loop but wanted to keep in the current loop
While Not project.EOF
i = i + 1
For ii = 1 To project.Fields.count
shtDetail.Cells(i, ii).Value = project.Fields(ii - 1).Value
Cells(i, "T").Formula = _
"=IFERROR(INDEX(data!B:B,MATCH(R4,data!A:A,0)),0)"
Next
project.MoveNext
Wend
EDIT your indenting is a bit off so my answer was not great: more like this:
While Not project.EOF
i = i + 1
For ii = 1 To project.Fields.count
shtDetail.Cells(i, ii).Value = project.Fields(ii - 1).Value
Next ii
shtDetail.Cells(i, "T").Formula = _
"=IFERROR(INDEX(data!B:B,MATCH(R" & i & ",data!A:A,0)),0)"
project.MoveNext
Wend
I'm not following your comments about adding quotes - adding them to what?

Excel Sequential Numbering order based on hierarchy position of data

I need to add sequential numbering order in excel based on the list position of data within excel. I have tried many things to get this right but surely there must be an easy solution.
As you can see my data is an ordered list of text where you can see the hierarchy in the offset of data down the rows. I am trying to automatically create the yellow picture based on the data from the left side.
The only solution I have come up with is to add columns in front of each column, filter the records based on non-blanks then work from left to right manually adding the sequence, but even this is too time intensive.
Ill be working on a macro next but thought there may be an easier solution using a formula. - will update if found.
This is probably not the most efficient solution, but it works:
Formula in G2 (fill the rest of the area with it):
=IF(ISBLANK(A2),IF(ISBLANK(B2),G1,G1+1),0)
Formula in L2 (fill the rest of the area with it):
=IF(G2>0,K2&"."&G2,"")
Formula in Q2 (fill the rest of the area with it):
=IF(ISBLANK(B2),"",MID(L2,2,LEN(L2))&" - "&B2)
You can easily use it for any depth by increasing the areas size, but you need an empty top row and empty column on the left of each area to make it work.
You could probably skip L:O area by combining the last two formulas.
Result:
Formulas: (blue are constants, orange are for the first hierarchy level, green are dragged in the box)
Sub Sequential_Numbering()
Dim tmpRange As Range, tmpArray(1 To 4) As Integer, x As Integer
Set tmpRange = Range("A1")
tmpArray(1) = 1
tmpRange.Value = tmpArray(1) & " - " & tmpRange.Value
For x = 2 To 13
Set tmpRange = Rows(x).Find(What:="*")
Select Case tmpRange.Column
Case 1
tmpArray(1) = tmpArray(1) + 1
tmpArray(2) = 0
tmpArray(3) = 0
tmpArray(4) = 0
tmpRange.Value = tmpArray(1) & " - " & tmpRange.Value
Case 2
tmpArray(2) = tmpArray(2) + 1
tmpArray(3) = 0
tmpArray(4) = 0
tmpRange.Value = tmpArray(1) & "." & tmpArray(2) & " - " & tmpRange.Value
Case 3
tmpArray(3) = tmpArray(3) + 1
tmpArray(4) = 0
tmpRange.Value = tmpArray(1) & "." & tmpArray(2) & "." & tmpArray(3) & " - " & tmpRange.Value
Case 4
tmpArray(4) = tmpArray(4) + 1
tmpRange.Value = tmpArray(1) & "." & tmpArray(2) & "." & tmpArray(3) & "." & tmpArray(4) & " - " & tmpRange.Value
End Select
Next x
End Sub

Visual Basic Excel For Loop In Multiple Cells How To Use The Counter In The Range("")

This is what I have, so the H needs to be followed by the number of the cell, I want to use the counter i here, but it doesn't work. What am I doing wrong? :)
For i = 60 To 63
Range("Hi").AddComment
Range("Hi").Comment.Visible = False
Range("Hi").Comment.Text Text:=""
i = i + 1
Range("Hi").Select
i = i - 1
Next
End Sub
Use this:
Range("H" & i)
As you wrote it, "Hi" does not use the variable i because you put it in quotes.
You need to do this instead:
For i = 60 To 63
Range("H" & i).AddComment
Range("H" & i).Comment.Visible = False
Range("H" & i).Comment.Text Text:=""
i = i + 1
Range("H" & i).Select
i = i - 1
Next
End Sub
The & operator does concatenation in VBA.
You should format it like this:
For i = 60 To 63
Range("H" & i).AddComment
Range("H" & i).Comment.Visible = False
Range("H" & i).Comment.Text Text:=""
i = i + 1
Range("H" & i).Select
i = i - 1
Next i
End Sub
The reason is that the letter H is a character and i is a variable. anything inside of double quotes "Hi" like that Excel will read as just a string of text.
When Excel reads a word or letter outside of quotes i it will assume it is a variable. The & character joins the two together as text.
This means that each time the loop runs Excel will read it as "H" and i and translate it to "H1", "H2", "H3", .... "H60" and input it into the Range() like you are looking for.
Would this work better for you? I've always had issues when the value of i starts chaging inside the loop code
For i = 60 To 63
With Range("H" & i)
.Select
.AddComment
.Comment.Visible = False
.Comment.Text Text:=""
end with
Next
End Sub

Resources