I recently created an IF formula to run inside a macro for only 2 statements but I need to add 3 more to it.
This is for altering a filename. So I use the LEN to determine what type of file it is then run the appropriate formula to trim out what I don't want.
Examples:
173d0221.pdf = S-173-D022 Description.pdf
=CHAR(83)&CHAR(45)&LEFT(B11,LEN(B11)-9)&CHAR(45)&UPPER(MID(B11,4,LEN(B11)-8))&CHAR(32)&D11&E11
173d02210.pdf = S-173-D022 Description.pdf =CHAR(83)&CHAR(45)&LEFT(B12,LEN(B12)-10)&CHAR(45)&UPPER(MID(B12,4,LEN(B12)-9))&CHAR(32)&D12&E12
173d170c141.pdf = SD-170-C14 Description.pdf
=CHAR(83)&CHAR(68)&CHAR(45)&UPPER(MID(B13,5,LEN(B13)-12))&CHAR(45)&UPPER(MID(B13,8,LEN(B13)-12)&CHAR(32)&D13&E13)
REF-173d0221.pdf = REF-173-D022 Description.pdf
=LEFT(B14,LEN(B14)-9)&CHAR(45)&UPPER(MID(B14,8,LEN(B14)-12))&CHAR(32)&D14&E14
REF-173d02210.pdf = REF-173-D022 Description.pdf
=LEFT(B15,LEN(B15)-10)&CHAR(45)&UPPER(MID(B15,8,LEN(B15)-13))&CHAR(32)&D15&E15
I am having trouble linking them together to get it to apply the right formula based on the length of the cell.
Notes: I am using CHAR(83)&CHAR(45) instead of "S-" because VBA wasn't liking the text. I will update the "B12" cell tag with " & aCell & " once everything is working smoothly.
My vba code looks like:
.Range("C2:C" & LastRow).Formula = "=IF(LEN(" & aCell & ")=12,CHAR(83)&CHAR(45)&LEFT(" & aCell & ",LEN(" & aCell & ")-9)&CHAR(45)&UPPER(MID(" & aCell & ",4,LEN(" & aCell & ")-8))&CHAR(32)&" & dCell & "&" & eCell & ",LEFT(" & aCell & ",LEN(" & aCell & ")-9)&CHAR(45)&UPPER(MID(" & aCell & ",8,LEN(" & aCell & ")-12))&CHAR(32)&" & dCell & "&" & eCell & ")"
This seems to work for the first three example formula.
I'll leave it to you to translate the remaining 2 formula to VBA, which you should be able to do following my examples :)
Option Explicit
Sub foo()
Dim rng As Range, aCell As Range
Dim val As String
Set rng = Range("B1:B5") '## Modify the input range as needed.
For Each aCell In rng.Cells
Select Case Len(aCell)
Case 12
val = "S-" & Left(aCell, Len(aCell) - 9) & "-" & Mid(aCell, 4, Len(aCell) - 8)
Case 13
val = "S-" & Left(aCell, Len(aCell) - 10) & "-" & Mid(aCell, 4, Len(aCell) - 9)
Case 15
val = "SD-" & Mid(aCell, 5, Len(aCell) - 12) & "-" & Mid(aCell, 8, Len(aCell) - 12)
Case 16
val = "REF-" '## Modify as needed
Case 17
val = "REF-" '## Modify as needed
Case Else
'maybe warn the user this input is not anticipated...
MsgBox "Unsupported length!", vbInformation
End Select
val = UCase(val)
'## Append the values from column D,E:
val = val & " " & aCell.Offset(, 2) & aCell.Offset(, 3)
'## Write out to the workbook in column F, modify the "5" to specify a different location if needed e.g., "-1" would put it in column A, "0" would put in same column B, etc.
aCell.Offset(, 4).Value = val
Next
End Sub
Related
I want to create a macro that check all the cells of a column and if the first two characters of a cell is "BB" then i want the macro to extract three characters from the cell and paste it to the next column but a the corresponding row.
But my formula after the if clause is not working.
this is what i have done since:
Sub test()
Dim lmid As String
Dim srange, SelData, ExtBbFor As String
Dim lastrow As Long
Dim i, icount As Integer
lastrow = ActiveSheet.Range("B30000").End(xlUp).Row
srange = "G1:G" & lastrow
SelData = "A1:G" & lastrow
Range(srange).Formula = "=mid(E1,1,3)"
For i = 1 To lastrow
If InStr(1, LCase(Range("E" & i)), "bb") <> 0 Then
Range("G" & i).Formula = "=mid("E & i", 4, 3)"
End If
Next i
End Sub
thanks in advance
Try with below. It will work
Range("G" & i).Value = Mid(Range("E" & i), 4, 3)
If the cell is not limited to 7 then you need as below
Range("G" & i).Value = "=Mid(E" & i & ", 3, " & Len(E & "& i & ") & ")"
It will extract from the 3rd character up to the last character in a cell.
Your syntax is wrong where you're trying to concatenate strings, I think you mean to use:
Range("G" & i).Formula = "=MID(E" & i & ",4,3)"
Based on your code I think this will do the exact same thing without having to loop or declare any variables:
Sub test()
With Range("G1:G" & Cells(Rows.Count, 2).End(xlUp).Row)
.FormulaR1C1 = "=IF(UPPER(LEFT(RC[-2],2))=""BB"",MID(RC[-2],4,3),"""")"
.Value = .Value
End With
End Sub
I'm having an issue that I am struggling to solve as it's a bit specific. I have code that does copy and paste from one sheet to others. Each part of the code basically copies part from the master sheet "current" to the specified sheet.
When I run my code I receive an error "Application defined or object defined error" and the code stops at the work sheet "Dividend yield" after the following line
Worksheets("div. yield").Range("B7").Select
However if I open the sheet "Dividend yield" and run my code from there it will work fine until the last sheet "Reverse PE" where it will again throw and error "Application defined or object defined error" after the line
Worksheets("Reverse_PE").Range("B9").Select
I guess the error is related to the next coming rows with Autofill method but I have not found any useful solutions to this problem. Could somebody please advise me how to solve this error?
Full macros code is below.
Function getYield() As Double
Dim appIE As Object
Set appIE = CreateObject("internetexplorer.application")
With appIE
.Navigate "http://uk.investing.com/rates-bonds/world-government-bonds"
.Visible = False
End With
Do While appIE.Busy
DoEvents
Loop
Set allRowOfData = appIE.document.getElementById("pair_23705")
Dim myValue As Double: myValue = allRowOfData.Cells(2).innerHTML
appIE.Quit
Set appIE = Nothing
Worksheets("Reverse_PE").Range("B7").Value = myValue
Worksheets("Reverse_PE").Range("B7").Value = Worksheets("Reverse_PE").Range("B7").Value / 100
End Function
Sub adjust()
Dim copyAdress As Range
Dim copyRange As Range
Dim lastRow As Long
Dim Median As Range
'''PE'''
Set copyAdress = Worksheets("current").Range("A1:CJ10000").Find("PE_RATIO", lookat:=xlPart)
lastRow = Cells(65536, copyAdress.Column).End(xlUp).Row
Set copyRange = Worksheets("current").Range(Cells(copyAdress.Row + 1, copyAdress.Column), Cells(lastRow, copyAdress.Column))
Worksheets("PE").Range("B1").EntireColumn.Insert
copyRange.Copy Destination:=Sheets("PE").Range("B7", "B" & lastRow)
Worksheets("PE").Range("B2").Value = Worksheets("current").Range("A1").Value
Worksheets("PE").Range("B3").FormulaArray = "=MEDIAN(B7:B" & lastRow + 2 & ")"
Worksheets("PE").Range("B5").Font.Bold = True
Worksheets("PE").Range("B5").FormulaArray = "=IF(ISNUMBER(VLOOKUP($A$5,$A$7:$HI$1750,COLUMN(B4),FALSE)),VLOOKUP($A$5,$A$7:$HI$1750,COLUMN(B4),FALSE)," & Chr(34) & NA & Chr(34) & ")"
Set copyRange = Worksheets("current").Range("A5", "A" & lastRow)
copyRange.Copy Destination:=Sheets("PE").Range("A7", "A" & lastRow + 2)
''Dividend yield'''
Set copyRange = Worksheets("current").Range("A5", "A" & lastRow)
copyRange.Copy Destination:=Sheets("div. yield").Range("A7", "A" & lastRow + 2)
Worksheets("div. yield").Range("B7").FormulaArray = "=IF(ISNUMBER(current!X5),current!X5," & Chr(34) & Chr(34) & ")"
Worksheets("div. yield").Range("B7").Select
Selection.AutoFill Destination:=Sheets("div. yield").Range("B7:B" & lastRow + 2), Type:=xlFillDefault
'''PE Forward'''
Set copyAdress = Worksheets("current").Range("A1:CJ10000").Find("P/E-Ratio 03E", lookat:=xlPart)
lastRow = Cells(65536, copyAdress.Column).End(xlUp).Row
Set copyRange = Worksheets("current").Range(Cells(copyAdress.Row + 3, copyAdress.Column), Cells(lastRow, copyAdress.Column))
Worksheets("PE_forward").Range("B1").EntireColumn.Insert
copyRange.Copy Destination:=Sheets("PE_forward").Range("B7", "B" & lastRow + 2)
Worksheets("PE_forward").Range("B2").Value = Worksheets("current").Range("A1").Value
Worksheets("PE_forward").Range("B3").FormulaArray = "=MEDIAN(B7:B" & lastRow + 2 & ")"
Worksheets("PE_forward").Range("B5").Font.Bold = True
Worksheets("PE_forward").Range("B5").FormulaArray = "=IF(ISNUMBER(VLOOKUP($A$5,$A$7:$HI$1750,COLUMN(B751),FALSE)),VLOOKUP($A$5,$A$7:$HI$1750,COLUMN(B751),FALSE)," & Chr(34) & NA & Chr(34) & ")"
Worksheets("PE_forward").Columns("B").Replace What:="#VALUE!", Replacement:=""
Worksheets("PE_forward").Range("B3").NumberFormat = ""
Set copyRange = Worksheets("current").Range("A5", "A" & lastRow)
copyRange.Copy Destination:=Sheets("PE_forward").Range("A7", "A" & lastRow + 2)
'''Reverse PE'''
Set copyRange = Worksheets("current").Range("A5", "A" & lastRow)
copyRange.Copy Destination:=Sheets("Reverse_PE").Range("A9", "A" & lastRow + 4)
Worksheets("Reverse_PE").Range("B1").EntireColumn.Insert
Worksheets("Reverse_PE").Range("B2").Value = Worksheets("current").Range("A1").Value
Worksheets("Reverse_PE").Range("B5").FormulaArray = "=IF(ISNUMBER(VLOOKUP($A$5,$A$9:$HI$1750,COLUMN(B751),FALSE)),VLOOKUP($A$5,$A$9:$HI$1750,COLUMN(B751),FALSE)," & Chr(34) & NA & Chr(34) & ")"
getYield
Worksheets("Reverse_PE").Range("B3").FormulaArray = "=MEDIAN(B9:B" & lastRow + 4 & ")"
Worksheets("Reverse_PE").Range("B9").FormulaArray = "=IF(ISNUMBER(PE!B7),1/PE!B7," & Chr(34) & Chr(34) & ")"
Worksheets("Reverse_PE").Range("B9").Select
Selection.AutoFill Destination:=Sheets("Reverse_PE").Range("B9:B" & lastRow + 4), Type:=xlFillDefault
Worksheets("Reverse_PE").Range("B3:B" & lastRow + 4).Select
Selection.Style = "Percent"
Selection.NumberFormat = "0.00%"
You can't use the select method unless the sheet is first active, so add this line:
Worksheets("div. yield").Activate
Worksheets("div. yield").Range("B7").FormulaArray = "=IF(ISNUMBER(current!X5),current!X5," & Chr(34) & Chr(34) & ")"
and later at:
Worksheets("Reverse_PE").Activate
Worksheets("Reverse_PE").Range("B9").Select
There are much faster and more maintainable ways of doing what you're trying to do, but the above sheet activation will solve your immediate problem.
Don't forget to activate each sheet before you try to select one of the cells on it.
I have a row of data (Cell A3 and down) that contains a Unix timestamp in yyyymmdd hhmmss format that I'm trying to convert to mm/dd/yy hh:mm format automatically.
The code I have so far works when I have the data starting in cell A1, but I need A1 to remain blank, therefore the data starts at A2. Here is an example screenshot of column A:
Sub auto_open()
'
' auto_open Macro
'
'
ChDir "C:\"
Workbooks.Open Filename:="C:\Users\username\Desktop\file1.csv"
Intersect(Sheets("file1").Range("A:EW"), Sheets("file1").UsedRange).Copy ThisWorkbook.Sheets("Golden").Range("A2")
Windows("file1.csv").Activate
Application.CutCopyMode = False
ActiveWorkbook.Close SaveChanges = False
Dim x As Integer
Dim y As String
Dim z As String
Dim w As String
NumRows = Range("A3").End(xlDown).Row
Windows(ThisWorkbook.Name).Activate
For x = 2 To NumRows
z = Cells(x, 1).Value
y = Mid(z, 5, 2) & "/" & Mid(z, 7, 2) & "/" & Left(z, 4)
w = Mid(z, 10, 2) & ":" & Mid(z, 12, 2) & ":" & Mid(z, 14, 2)
y = y + TimeValue(w)
Cells(x, 1).Value = y
Next x
Range("A3").Select
End Sub
It errors whether I set the range to A2 or A3 and down.
Does anyone have recommendations?
Debug highlights y = Mid(z, 5, 2) & "/" & Mid(z, 7, 2) & "/" & Left(z, 4) but I'm not sure what the problem is.
Format cells (custom > mm/dd/yyyy hh:mm:ss) also does not work in my case, unfortunately.
This will do it with no looping at all:
Sub kyle()
With [a3].Resize([a1048576].End(xlUp).Row - 2)
.Value = Evaluate("transpose(transpose(DATE(MID(" & .Address & ",1,4),MID(" & .Address & ",5,2),MID(" & .Address & ",7,2)) + TIME(MID(" & .Address & ",10,2),MID(" & .Address & ",12,2),MID(" & .Address & ",14,2))))")
End With
End Sub
Note: you can then use whatever number formatting for the dates you please.
Try this:
Sub Kyle()
Dim cell As Range
ThisWorkbook.Activate
For Each cell In Range("A2", Cells(Rows.Count, "A").End(xlUp))
If cell.Value Like "######## ######" Then
cell.Value = CDate(Format(cell.Value, "####-##-#####:##:##"))
End If
Next cell
End Sub
Then format the column however you prefer.
For me, that converts
20150904 213613
20150124 194003
20150404 163056
20151220 100509
20150510 213512
to this:
09/04/2015 21:36
01/24/2015 19:40
04/04/2015 16:30
12/20/2015 10:05
05/10/2015 21:35
#ExcelHero answered my question via email. The following is the working code for anyone who needs future reference.
With [a3].Resize([a65536].End(xlUp).Row - 2)
If Len(.Item(1)) = 15 Then
.Value = Evaluate("transpose(transpose(DATE(MID(" & .Address & ",1,4),MID(" & .Address & ",5,2),MID(" & .Address & ",7,2)) + TIME(MID(" & .Address & ",10,2),MID(" & .Address & ",12,2),MID(" & .Address & ",14,2))))")
End If
.NumberFormat = "mm/dd/yyyy hh:mm"
End With
So I'm trying to do a couple things with this subroutine but can't get VBA to execute the .FormulaArray function.
Create a named range using offset & lastrow function
Use cell references to insert into the array formula
--
Sub namedrange()
Dim firstrow As Long
Dim LastRow As Long
Dim ColToLetter, absolute, Title, mc, mc1
ActiveCell.Offset(0, -1).Select
absolute = ActiveCell.Address
LastRow = ActiveSheet.Cells(Rows.Count, ActiveCell.Column).End(xlUp).Row
firstrow = ActiveCell.Row
ColLetter = Mid(ActiveCell.Address, 2, 1)
ActiveSheet.Range(ColLetter & firstrow & ":" & ColLetter & LastRow).Name = Range(ColLetter & "1").Value
Title = Range(ColLetter & "1").Value
ActiveCell.Offset(0, 1).Select
mc = ActiveCell.Offset(-1, 0).Address
mc = Mid(mc, 2, 3)
mc1 = Replace(mc, "$", "")
ActiveCell.FormulaArray= "=IF(ROWS(mc & "":"" & mc1)>SUM(IF(FREQUENCY(IF(Title<>"""",MATCH(Title,Title,0)),ROW(Title)-ROW(absolute)+1),1)),"""",INDEX(Title,SMALL(IF(FREQUENCY(IF(Title<>"""",MATCH(Title,Title,0)),ROW(Title)-ROW(absolute)+1),ROW(Title)-ROW(absolute)+1),ROWS(mc & "":"" & mc1))))"
End Sub
The formula bar shows what the vba function is outputting, which is not what I want. I don't know why it won't output the references I've created like mc should be "$A$2" not "mc".
Also when I try to execute the FormulaArray code I get a runtime error 1004 "Unable to set the FormulaArray property of the Range class"
Your .FormulaArray content has some typos. Here's how it should look like (assuming all the above code is fine):
ActiveCell.FormulaArray= "=IF(ROWS(" & mc & ":" & mc1 & ")>SUM(IF(FREQUENCY(IF(Title<>" & chr(34) & chr(34) & ",MATCH(Title,Title,0)),ROW(Title)-ROW(absolute)+1),1))," & chr(34) & chr(34) & ",INDEX(Title,SMALL(IF(FREQUENCY(IF(Title<>" & chr(34) & chr(34) & ",MATCH(Title,Title,0)),ROW(Title)-ROW(absolute)+1),ROW(Title)-ROW(absolute)+1),ROWS(" & mc & ":" & mc1 & "))))"
In general, remember that if you want the value of a variable to be printed into a string, you cannot write "a=mc+3" but rather a = " & mc & "+3".
I need help with my puzzle. I have written a code that works fine. Now a user wants to see not just the final result but also the formula written in VBA (for audit purposes) to verify that the results are OK. Is there a way to show BOTH results and formula in the same cell?
My code so far:
Sub Vlookup_Condition_VAT_table()
Dim Rng As Range
Dim i As Long
Application.ScreenUpdating = False
Workbooks("GST_recovery_overclaim.xlsm").Worksheets("MonthlyData_Raw").Activate
'Identify the Destination location to start populating vlookuped values
Range("AK2").Activate
With Worksheets("MonthlyData_Raw").Cells
Set Rng = .Range("A1:A" & .Cells(.Rows.Count, 1).End(xlUp).Row)
For i = 2 To Rng.Rows.Count
'populate the destination range with
'vlookup values from the list vlookup table
Rng.Cells(i, 37) = Application.VLookup(.Cells(i, 28), Sheets("VAT_apportionment_table_201310").Range("D:G"), 4, False)
Next
End With
Application.ScreenUpdating = True
End Sub
Thank you very much,
Russ
If you aren't looking at thousands of rows, you could try the following.
Instead of using this line to print the result of your vlookup formula:
Rng.Cells(i, 37) = Application.VLookup(.Cells(i, 28), Sheets("VAT_apportionment_table_201310").Range("D:G"), 4, False)
You could instead put the actual formula in the cell with this change
Rng.Cells(i, 37).Formula = "=VLOOKUP(" & _
.Cells(i, 28).Address & "," & _
"'" & Sheets("VAT_apportionment_table_201310").name & "'!D:G," & _
"4," & _
"False)"
--------------UPDATE BASED ON OP COMMENT-----------------------------
Adding error trapping via an ISERROR function (untested)
Dim errMsg as String
errMsg = "Not in exception list"
Rng.Cells(i, 37).Formula = "=ISERROR(VLOOKUP(" & _
.Cells(i, 28).Address & "," & _
"'" & Sheets("VAT_apportionment_table_201310").name & "'!D:G," & _
"4," & _
"False), " & errMsg & ")"
I created a variable for the error message for a couple of reasons.
Easier to debug later
Dealing with text in a formula that is being sent to the cell like this can be tricky. And using a variable gets around the trickiness.
Maybe add text to the result with the answer and the formula.
Rng.Cells(i, 37) = "Answer: " & Application.VLookup(.Cells(i, 28), Sheets("VAT_apportionment_table_201310").Range("D:G"), 4, False) & ", Formula: = Application.VLookup(.Cells(i, 28), Sheets("VAT_apportionment_table_201310").Range("D:G"), 4, False)"
If I undestood you correctly, you want to display the formula entered in a cell with the result. How about this?
'Assume that you have a Range("A1") equals to = cos(20)
Sub GetFormula()
Dim MyFormula As String
MyFormula = Replace(Range("A1").Formula, "=", "")
MsgBox ("Formula is : " & MyFormula _
& " Result is :" & Range("A1"))
End Sub