I’m currently trying to include a VBA code into a larger Macro however one particular line (in Part B) is throwing out an error with the FIND function. The objective of the code is to insert two formulas into two diiferrent cells that extract text string from other cell (this formula is copied down accordingly). Below is what I have to date
' Part A
x = Range("A" & Rows.Count).End(xlUp).Row
sConc = "=B2&"" - ""&XLOOKUP(B2,Table4[Code], Table4[Description])"
Range("J2").Resize(x - 1).Formula = sConc
' Part B
y = Range("B" & Rows.Count).End(xlUp).Row
sConc = (LEFT(G1,FIND(" - ",G1)+1)) ' THIS LINE
Range("K2").Resize(y - 1).Formula = sConc
I gather the FIND function will not work within VBA and I need to use the INSTR function however I cannot figure out how to extract the required text ( before the " - ") from the cell using the INSTR function.
Any help on this would be greatly appreciated
Thanks
Related
I'm trying to dynamically populate a couple of cells in Excel with VBA with some simple formulas.
I need a formula like
=(B1-C2)
In Excel
Which is very simple to code... But I get a application or object defined error '1004'. With this simple loop.
For i = 1 To 3
Range("A" & i).Value = "=("
Next i
Therefore I tried to first declare a variable like
dim tmp as string
tmp = "=("
For i = 1 To 3
Range("A" & i).Value = tmp
Next i
But it did not work.
I have also tried to declare it as variant but with no luck.
Does anyone why this happens and how to fix it? Thanks
I belive that this is possible with my limited knowldge of vba. I am trying to add more information to a pre-exsiting formula within a workbook.
Currently the formula is as follows, in Cells(SnapshotStartRow-2,11) the formula is =SUM('GK034'!B5 + 'GK034'!B21 + 'GK034'!B34)
The next stage is add an extra cell addition to the equation to look like
=SUM('GK034'!B5 + 'GK034'!B21 + 'GK034'!B34+ 'GK034'!B50)
My idea was to use this code below;
With Worksheets("Snapshot")
sAddress1 = .Cells(SnapshotStartRow - 2, 11).Address(0, 0)
End With
With Worksheets(SnapshotArray(i, 1))
sAddress2 = Worksheets(SnapshotArray(i, 1)).Cells(NewEngineRowNumber + 2, 2).Address(External = True)
End With
With Worksheets("Snapshot")
sFormula = "=Sum(" & sAddress1 & "+" & sAddress2 & ")"
.Cells(SnapshotStartRow - 2, 11).Formula = sFormula
End With
Some info on this code,
SnapshotArray(i,1) is there a reference for finding the sheet and contain the value GK034
SnapshotStartRow is used to defined a previously needed row reference and is equal to 125.
NewEngineRowNumber is used to define a previously needed adrress and is equal to 48
The idea behind the code was to take the current formular and mearly add the new cell to it.
Howevver there were a few issue that I failed to forsee,
Firstly, the 1st with loop mearly took the value of the cell rather than the exsisting formular.
Secondly the equation failed to remember which sheets the data was taken from.
Once i ran the code I ended up with, in the correct cell (The only part of the code that worked)
= SUM(K123 + $B$50)
Where K123 is the correct cell that use to contain the formular and B50 is desired cell on a different worksheet.
However K123 is now 0 and $B$50 dosen't refer to the desired workbook.
If anyone is able to help me that would be greatly appriciated. I will keep updatingthe post as i try new methods.
having done some more resurch I belive I need to extract the current formula as a string, which I belive can be done with a function, below.
Function CellFormula(Rng As Range) As String
CellFormula = Rng.Formula
End Function
Then could you add to the string the new code `$b$50 with the correct worksheet, then somehow paste the new string into the formula bar? Is that even possible?
From QHar comments, I tried to concatenate the worksheet name using,
With Worksheets(SnapshotArray(i, 1))
sAddress2 = Worksheets(SnapshotArray(i, 1)).Name & .Cells(NewEngineRowNumber + 2, 2).Address(External = yes)
End With
This didn't work either and noticed that parts of the equation were missing, I tried to add them manually and this failed to work, see below.
With Worksheets(SnapshotArray(i, 1))
sAddress2 = "'" & Worksheets(SnapshotArray(i, 1)).Name & "'!" & .Cells(NewEngineRowNumber + 2, 2).Address(External = yes)
End With
I have two columns with data. The first one has some terms and the other one contains single words.
what I have
I'm looking for a way to identify which words from each cell from the first column appear in the second, so the result should look something like this (I don't need the commas):
what I need
My question is somehow similar to Excel find cells from range where search value is within the cell but not exactly, because I need to identify which words are appearing in the second column and there can be more than one word.
I also tried =INDEX($D$2:$D$7;MATCH(1=1;INDEX(ISNUMBER(SEARCH($D$2:$D$7;A2));0);))
but it also returns only one word.
If you are willing to use VBA, then you can define a user defined function:
Public Function SearchForWords(strTerm As String, rngWords As Range) As String
Dim cstrDelimiter As String: cstrDelimiter = Chr(1) ' A rarely used character
strTerm = cstrDelimiter & Replace(strTerm, " ", cstrDelimiter) & cstrDelimiter ' replace any other possible delimiter here
SearchForWords = vbNullString
Dim varWords As Variant: varWords = rngWords.Value
Dim i As Long: For i = LBound(varWords, 1) To UBound(varWords, 1)
Dim j As Long: For j = LBound(varWords, 2) To UBound(varWords, 2)
If InStr(1, strTerm, cstrDelimiter & varWords(i, j) & cstrDelimiter) <> 0 Then
SearchForWords = SearchForWords & varWords(i, j) & ", "
End If
Next j
Next i
Dim iLeft As Long: iLeft = Len(SearchForWords) - 2
If 0 < iLeft Then
SearchForWords = Left(SearchForWords, Len(SearchForWords) - 2)
End If
End Function
And you can use it from the Excel table like this:
=SearchForWords(A2;$D$2:$D$7)
I have a partial solution:
=IF(1-ISERROR(SEARCH(" "&D2:D7&" "," "&A2&" ")),D2:D7&", ","")
This formula returns an array of the words contained in the cell (ranges are according to your picture). This array is sparse: it contains empty strings for each missing word. And it assumes that words are always separated by one space (this may be improved if necessary).
However, native Excel functions are not capable of concatenating an array, so I think the rest is not possible with native formulas only.
You would need VBA but if you use VBA you should not bother with the first part at all, since you can do anything.
You can create a table with the words you want to find across the top and use a formula populate the cells below each word if it's found. See screenshot.
[edit] I've noticed that it's incorrectly picking up "board" in "blackboard" but that should be easily fixed.
=IFERROR(IF(FIND(C$1,$A2,1)>0,C$1 & ", "),"")
Simply concatinate the results
=CONCATENATE(C2,D2,E2,F2,G2,H2)
or
=LEFT(CONCATENATE(C2,D2,E2,F2,G2,H2),LEN(CONCATENATE(C2,D2,E2,F2,G2,H2))-2)
to take off the last comma and space
I've edited this to fix the problem with "blackboard"
new formula for C2
=IF(OR(C$1=$A2,ISNUMBER(SEARCH(" "&C$1&" ",$A2,1)),C$1 & " "=LEFT($A2,LEN(C$1)+1)," " & C$1=RIGHT($A2,LEN(C$1)+1)),C$1 & ", ","")
New formula for B2 to catch the error if there are no words
=IFERROR(LEFT(CONCATENATE(C2,D2,E2,F2,G2,H2,I2),LEN(CONCATENATE(C2,D2,E2,F2,G2,H2,I2))-2),"")
I am trying to create a function or functions that can sum daily hours from time cards for each client to come up with the total hours worked per day. Each client has it's own sheet inside of a single workbook.
Currently, I have a function that determines the sheet that goes with the first client (the third sheet in the workbook):
Function FirstSheet()
Application.Volatile
FirstSheet = Sheets(3).Name
End Function
And one to find the last sheet:
Function LastSheet()
Application.Volatile
LastSheet = Sheets(Sheets.Count).Name
End Function
The part that I am having trouble with it getting these to work within the sum function.
=sum(FirstSheet():LastSheet()!A1
That is basically what I want to accomplish. I think the problem is that I don't know how to concatenate it without turning it into a string and it doesn't realize that it is sheet and cell references.
Any help would be greatly appreciated.
So, an example formula would look like this:
=SUM(Sheet2!A1:A5,Sheet3!A1:A5,Sheet4!A1:A5)
That would sum Sheet2-Sheet4, A1:A5 on all sheets.
Is there a reason you need to write the VBA code to do this?
Can't you just enter it as a formula once?
Also, if you're going to the trouble of writing VBA to generate a formula, it may make more sense to just do the sum entirely in VBA code.
If not, try this:
Sub GenerateTheFormula()
Dim x, Formula
Formula = "=SUM(" 'Formula begins with =SUM(
For x = 3 To Sheets.Count
Formula = Formula & Sheets(x).Name & "!A1," 'Add SheetName and Cell and Comma
Next x
Formula = Left(Formula, Len(Formula) - 1) & ")" 'Remove trailing comma and add parenthesis
Range("B1").Formula = Formula 'Where do you want to put this formula?
End Sub
Results:
The functions return strings and not actual worksheets. The Worksheet does not parse strings well. So add a third function that uses the Evaluate function:
Function MySum(rng As Range)
MySum = Application.Caller.Parent.Evaluate("SUM(" & FirstSheet & ":" & LastSheet & "!" & rng.Address & ")")
End Function
Then you would simply call it: MySum(A1)
It uses the other two function you already have created to create a string that can be evaluated as a formula.
I didn't understand ur question completely but As I understood u have different sheets of different clients which contains supoose column 1 date and column 2
contains hours on that particular date wise hours and a final sheet which column1 contains name of client and column 2 contains total hoursPlease try it
Sub countHours()
Dim last_Row As Integer
Dim sum As Double
sum = 0
'Because I know number of client
For i = 1 To 2 'i shows client particular sheet
last_Row = Range("A" & Rows.Count).End(xlUp).Row
Sheets(i).Activate
For j = 2 To last_Row
'In my Excel sheet column 1 contains dates and column 2 contains number of hours
sum = sum + Cells(j, 2)
'MsgBox sum
Next j
'Sheet 3 is my final sheet
ThisWorkbook.Sheets(3).Cells(i + 1, 2).Value = sum
sum = 0
Next i
End Sub
Happy Coding :
I have gotten so much excellent help from this site. This is my first question. I have googled all the wordings I can think of and looked at all possible related threads on this site and others, and cannot find an explanation.
I am trying to automate a sheet into which a data table of variable size will be pasted.
Here is the formula I am trying to replicate:
=(C26-B26)/B26 (percent variation to previous month)
Edited to respond to a comment: This formula is in cell C28 in the sheet I am being asked to automate. So it is referring to cells two rows above and 1 column to the left of the cell where the formula is located.
Here is my code which the editor accepts:
ActiveCell.Formula = "=(" & (Cells(Index(Row() - 2), Index(Col())).Address(False, False)) & "-" & Cells(Index(Row() - 2), Index(Col() - 1)).Address(False, False) & "/" & Cells(Index(Row() - 2), Index(Col() - 1)).Address(False, False) & ")"
When I run this, I get a compile error: Sub or Function not defined and the first instance of row is highlighted.
It seems to me I read somewhere that one cannot calculate with Row() and Column() but I have not been able to find that again. I have found many examples online of people using Row() and Column() in this way to find cells adjacent to the active cell.
I appreciate any help and suggestions.
Thank you in advance.
I'd determine the indices of your reference cell (the one that's not known). In the example below, I'm simply using the indices and converting them to characters from ASCII and concatenating the returned character and the row number.
Dim activeRow, activeColumn As Integer
activeRow = 40 'Iterate through or use Range reference as Range.Row
activeColumn = 3 'Iterate through or use Range reference as Range.Column
MsgBox ("=(" & Chr(64 + activeColumn) & (activeRow - 2) & "-" & Chr(64 + activeColumn - 1) & (activeRow - 2) & "/" & Chr(64 + activeColumn - 1) & (activeRow - 2) & ")")
Update:
Also take a look at this question for referencing the instance of the calling cell in a Public Function, specifically Fionnuala's answer.