Simple Visual basic q in an excel macro - excel

Dim test As String
test = CStr(ActiveWorkSheet.VLookup("jpeg_lrg", B, 3))
stupid 424 error help!
for my macro in excel vba
Dim test As String
test = CStr(ActiveWorkSheet.VLookup("jpeg_lrg", B44, 3))
(didnt work as well)
also tried without the CSTR

You can't just pass you ranges as variable names.
Dim test As String
test = Application.WorksheetFunction.VLookup("jpeg_lrg", ActiveSheet.Range("B:B"), 3)
That won't make any sense though, because "B:B" only contains one column, and you ask it for column three. With VLookup you want at least two columns in the range.

I think you are trying to return the value of the cell of E44?
If that is the case, then this should work for you - replace MsgBox with the code you require.
For Each i In Range("B44")
If i = "jpeg_lrg" Then
MsgBox i.Offset(0, 2)
Else
End If
Next i

Related

Convert vlookup to more than 255 characters via Excel VBA

I am looking for reverse vlookup with more than 255 characters in Excel VBA.
This is the formula based one which I took from this website.
=INDEX(F2:F10,MATCH(TRUE,INDEX(D2:D10=A2,0),0))
I have try to convert it in VBA. Here below sample code
Sub test()
'concat
Range("i1") = WorksheetFunction.TextJoin(" ", True, Range("g1:h1"))
'lookup
Sal1 = Application.WorksheetFunction.Index(Sheets("sheet1").Range("a1:a2"), Application.WorksheetFunction.Match(True, Application.WorksheetFunction.Index(Sheets("sheet1").Range("i1:i1") = Range("i1").Value, 0), 0))
'=INDEX($W$3:$W$162,MATCH(TRUE,INDEX($W$3:$W$162=U3,0),0))
End Sub
It works well but it didn't when i change the range("i1:i1") to range("i1:i2")
I'm not sure what that worksheet formula does that =INDEX(F2:F11,MATCH(A2,D2:D11,FALSE)) doesn't do.
This part Index(Sheets("sheet1").Range("i1:i2") = Range("i1").Value, 0) is comparing a 2-d array to a single value, which should result in a Type Mismatch error. Whenever you reference a multi-cell range's Value property (Value is the default property in this context), you get a 2-d array even if the range is a single column or row.
You could fix that problem with Application.WorksheetFunction.Transpose(Range("D1:D10")) to turn it into a 1-d array, but I still don't think you can compare a 1-d array to a single value and have it return something that's suitable for passing into INDEX.
You could use VBA to create the array's of Trues and Falses, but if you're going to go to that trouble, you should just use VBA to do the whole thing and ditch the WorksheetFunction approach.
I couldn't get it to work when comparing a single cell to a single cell like you said it did.
Here's one way to reproduce the formula
Public Sub test()
Dim rFound As Range
'find A2 in D
Set rFound = Sheet1.Range("D1:D10").Find(Sheet1.Range("A2").Value, , xlValues, xlWhole)
If Not rFound Is Nothing Then
MsgBox rFound.Offset(0, 2).Value 'read column f - same position as d
End If
End Sub
If that simpler formula works and you want to use WorksheetFunction, it would look like this
Public Sub test2()
Dim wf As WorksheetFunction
Set wf = Application.WorksheetFunction
MsgBox wf.Index(Sheet1.Range("F2:F11"), wf.Match(Sheet1.Range("A2").Value, Sheet1.Range("D2:D11"), False))
End Sub
Function betterSearch(searchCell, A As Range, B As Range)
For Each cell In A
If cell.Value = searchCell Then
betterSearch = B.Cells(cell.Row, 1)
Exit For
End If
betterSearch = "Not found"
Next
End Function
i found this code from above link and it is useful for my current search.Below examples i try to get value..
Kindly consider Row 1 to 5 as empty for A and B column because my table always start from Row 6
Row
A Column
B Column
6
54
a
7
55
b
8
56
c
VBA Code:
Sub look_up ()
Ref = "b"
look_up = betterSearch(Ref, Range("B6:B8"), Range("A6:A8"))
End Sub
it show Empty while use Range("B6:B8"), Range("A6:A8")
but when changing the range from B6 and A6 to B1 and A1 (Range("B1:B8"), Range("A1:A8") )it gives the value...
My question is "can get the values from desired range"
Expressing matches via VBA
I like to know if there (are) any possibilities to convert this formula.
=INDEX(F2:F10,MATCH(TRUE,INDEX(D2:D10=A2,0),0))
So "reverse VLookUp" in title simply meant to express the (single) formula result via VBA (btw I sticked to the cell references in OP, as you mention different range addresses in comments).
This can be done by simple evaluation to give you a starting idea:
'0) define formula string
Dim BaseFormula As String
BaseFormula = "=INDEX($F$2:$F$10,MATCH(TRUE,INDEX($D$2:$D$10=$A2,0),0))"
'1) display single result in VB Editor's immediate
Dim result
result = Evaluate(BaseFormula)
Debug.Print IIf(IsError(result), "Not found!", result)
On the other hand it seems that you have the intention to extend the search string range
from A2 to more inputs (e.g. till cell A4). The base formula wouldn't return a results array with this formula,
but you could procede as follows by copying the start formula over e.g. 3 rows (note the relative address ...=$A2 to allow a row incremention in the next rows):
'0) define formula string
Dim BaseFormula As String
BaseFormula = "=INDEX($F$2:$F$10,MATCH(TRUE,INDEX($D$2:$D$10=$A1,0),0))"
'2) write result(s) to any (starting) target cell
'a)Enter formulae extending search cells over e.g. 3 rows (i.e. from $A2 to $A4)
Sheet3.Range("H2").Resize(3).Formula2 = BaseFormula
'b) optional overwriting all formulae, if you prefer values instead
'Sheet3.Range("H2").Resize(3).Value = Tabelle3.Range("G14").Resize(3).Value
Of course you can modify the formula string by any dynamic replacements (e.g. via property .Address(True,True,External:=True) applied to some predefined ranges to obtain absolute fully qualified references in this example).
Some explanations to the used formulae
The formula in the cited link
=INDEX(F2:F10,MATCH(TRUE,INDEX(D2:D10=A2,0),0))
describes a way to avoid an inevitable #NA error when matching strings with more than 255 characters directly.
Basically it is "looking up A2 in D2:D10 and returning a result from F2:F10" similar to the (failing) direct approach in such cases:
=INDEX(F2:F11,MATCH(A2,D2:D11,FALSE))
The trick is to offer a set of True|False elements (INDEX(D2:D10=A2,0))
which can be matched eventually without problems for an occurence of True.
Full power by Excel/MS 365
If, however you dispose of Excel/MS 365 you might even use the following much simpler function instead
and profit from the dynamic display of results in a so called spill range.
That means that matches can be based not only on one search string, but on several ones (e.g. A1:A2),
what seems to solve your additional issue (c.f. last sentence in OP) to extend the the search range as well.
=XLOOKUP(A1:A2,D2:D10,F2:F10,"Not found")

Excel VBA - Add one to each referenced cell when running macro

I have tried searching for the answer for the past couple hours but cannot seem to find what I am looking for - mind you, I am really new to VBA and macros.
What I am trying to do is to add one to what my formula is referencing to every time the macro is run. For example:
Currently the formula is =100*((Q$179/Q$167)-1)
When run, I would like it to be =100*((Q$180/Q$168)-1)
I have to do this for multiple formulas. Is there an easy way to do this with a macro?
Thank you so much in advance
Personally I'd use RegEx to achieve this. The following will increment every cells row by 1 in your formula. This should also work on columns other then Q as well
Option Explicit
Sub IncrementFormula()
Dim tmpFormula As String
Dim RegEx As Object
Dim Match, SubMatch
tmpFormula = "=100*((Q$179/Q$167)-1)"
Set RegEx = CreateObject("vbscript.regexp")
With RegEx
.Global = True
.Pattern = "(?:[A-Z]{1,})(?:\$|)([0-9]{1,})"
If .test(tmpFormula) Then
For Each Match In .Execute(tmpFormula)
For Each SubMatch In Match.submatches
tmpFormula = Replace(tmpFormula, Match, Replace(Match, SubMatch, vbNullString) & CLng(SubMatch) + 1)
Next SubMatch
Next Match
End If
End With
MsgBox tmpFormula
End Sub
Using your formula above it will output =100*((Q$180/Q$168)-1)
If you want it to persist when the workbook is closed, you'll need to store your number somewhere in a worksheet. Say it's in Cell(1,1) of Sheets(2), you could use
dim incVal as integer
incVal = cint(Sheets(2).Cells(1,1))+1
Sheets(2).Cells(1,1) = incVal
dim formula as string
formula = "=100*((Q$" & incVal & "/Q$" & (incVal-12) & ")-1)"
Then just set the desired Cell's formula to that formula. Hope this helps.
A different approach is to use OFFSET in your formula
Assuming the formula is in Q185
then:
=100*((Q$180/Q$168)-1)
Becomes:
=100*((OFFSET(Q185,-5,0)/OFFSET(Q185,-17,0)-1))
As you insert rows at the bottom of the table (and above the formulas), the formula and the cell it refers to will also move down

VBA Excel Formula, error 1004

I'm trying to input a formula in a cell after inserting a row. And VBA does not want that and returns an error.
I first copied the formula from the excel sheet, (with ";" as delimitors), and as I have seen on other threads, I replace those with ",".
I don't understand why I get the error.
Sub Borderx()
Dim nboc As Integer
Dim ipaste As Integer
nboc = Worksheets("BDD").Range("IQ2").Value
For ipaste = 1 To nboc - 1
Worksheets("Bordereaux").Range("B14").EntireRow.Insert
Worksheets("Bordereaux").Range("T14").Formula = "=IF(AND(J14="",E14=""),SUM(F14*F14*H14)/1000,IF(O14="",SUM((H14*F14*G14)+(M14*K14*L14))/1000,SUM((H14*F14*G14)+(M14*K14*L14)+(R14*P14*Q14))/1000))"
Next ipaste
End Sub
In this case, nboc = 2, and this is supposed to insert one row.
Before I added the "if" statement, it worked fine when it was just sum()
Change it like this:
Worksheets("Bordereaux").Range("T14").Formula = " =IF(AND(J14="""",E14=""""),SUM(F14*F14*H14)/1000,IF(O14="""",SUM((H14*F14*G14)+(M14*K14*L14))/1000,SUM((H14*F14*G14)+(M14*K14*L14)+(R14*P14*Q14))/1000))"

Selecting Data between sheets to Write a Vlookup function

I Have a data in sheet(Sales Data) form Cells B7:B207 and I'm trying to write a vba code for using data to generate Vlookup function in sheet(Salesmen Info). But I failed to generate the VBA Code. Please advise how would I generate the VLookup in (Salesmen Info).
you could just vlookup outside of VBA with a standard function
=vlookup(A1,"Sales Data"!$B$7:$B$207,1,false)
If your VBA is failing, make sure you reference the sheet "sales data" in quotation marks whenever you call it. What's your current VBA code?
Additionally, why are you trying to vlookup a single column (B). You need your range to be at least 2 columns so it can find the data in B and return the data from C
I like applciation.vlookup:
arr = application.vlookup(A1,"Sales Data"!$B$7:$B$207,1,false)
then, this should work (typing without excel handy so it might not!):
for i = 0 to ubound(arr,0)
for j = 0 to ubound(arr,1)
debug.print arr(i,j)
next
next
(Press Ctrl+J to see the immediate window and see your output)
or maybe you want it in a sheet?
dim rng as range
set rng = range("A1")
for i = 0 to ubound(arr,0)
for j = 0 to ubound(arr,1)
rng.offset(i,j).value = arr(i,j)
next
next

Exceeding Max Char Limit in Excel

How do I use more than 255 characters in Excel's CONCATENATE function? I am actually also using the CONCATENATE function within the HYPERLINK function in EXCEL. An example looks like this:
=HYPERLINK(CONCATENATE("http://www.google/com/morethan255charsmorethan255charsmorethan255charsmorethan255charsmorethan255charsmorethan255charsmorethan255charsmorethan255charsmorethan255charsmorethan255chars","morethan255chars morethan255charsmorethan255charsmorethan255charsmorethan25"),"link");
UPDATE: It's not issue with CONCATENATE function, but an issue with the first parameter of the HYPERLINK function. Using a string longer than 255 characters directly/indirectly (ex: =HYPERLINK(K204,"link") where K204 contains the 256-character length link) fails the HYPERLINK function
I realize that I can use a URL shortener, but I am doing this for ALOT of links which would require ALOT of manual use of the URL shortener.
UPDATE: Because of Karls comment I revisited my answer an found out, that Excel 2007 does not seem to allow User Defined Functions to set hyperlinks anymore (quite sensibly, see my own comment in the code). So the original code (below the line) does not work in more recent versions of Excel (I haven't tested Excel 2010 but I assume the result is the same). For historical reasons I do not delete the old code (an editor might think otherwise -- feel free to edit/ delete accordingly).
So what remains is to set long hyperlinks programatically, e.g.
Sub insertVeryLongHyperlink()
Dim curCell As Range
Dim longHyperlink As String
Set curCell = Range("A1") ' or use any cell-reference
longHyperlink = "http://www.veryLongURL.com/abcde" ' Or a Cell reference like [C1]
curCell.Hyperlinks.Add Anchor:=curCell, _
Address:=longHyperlink, _
SubAddress:="", _
ScreenTip:=" - Click here to follow the hyperlink", _
TextToDisplay:="Long Hyperlink"
End Sub
What follows does not work in Excel 2010 anymore; see my comment above
The "copy the hyperlink from Word and paste into Excel" got me thinking. So obviously the limit is both in the built-in HYPERLINK-function and in the dialog-window 'edit hyperlink'. On the other hand it should be -- and actually is -- possible to set longer hyperlinks via VBA.
This code does not work in Excel 2010 anymore
Function myHyperlink(cell As Range, _
hyperlinkAddress As String, _
Optional TextToDisplay As Variant, _
Optional ScreenTip As Variant)
' Inserts a Hyperlink
' at the position cell (this should be the position where the UDF is used,
' since the return value of the UDF is = TextToDisplay)
' with the hyperlinkAddress
' optional TextToDisplay
' optional ScreenTip
' #######################################
' Warning Warning Warning Warning Warning
' #######################################
' 1) Since it is really bad practice to have a function perform procedural
' tasks, you should not do this.
' 2) You have no garantee, the link is updated when the value hyperlinkAddress changes
' USE AT YOUR ONE RISK AND ONLY IN CASE OF EMERGENCIES :-)
' If more than one cell is selected as target range,
' use the top left cell
Set cell = cell.Resize(1, 1)
If IsMissing(TextToDisplay) Then
TextToDisplay = hyperlinkAddress
End If
If IsMissing(ScreenTip) Then
ScreenTip = hyperlinkAddress & " - Click here to follow the hyperlink"
End If
cell.Hyperlinks.Add Anchor:=ActiveCell, _
Address:=hyperlinkAddress, _
SubAddress:="", _
ScreenTip:=ScreenTip, _
TextToDisplay:=TextToDisplay
' There doesn't seem to be another way to set TextToDisplay
myHyperlink = TextToDisplay
End Function
Use as a normal Excel-function, but be sure to add the current cell as first parameter (i.e. the following formula is inserted in cell A1)
=myHyperlink(A1,B1)
=myHyperlink(A1,B1,"TextToDisplay", "ScreenTip")
You can neither pull the formula down nor copy it to another cell. If you do that you have to let the formula be recalculated (neither ALT-CTRL-F9 nor ALT-CTRL-SHIFT-F9 as force recalculate seem to work) so go into each cell, press F2 to activate it and finish with Return.
I hope I am not helping you to screw up too many Excel-Workbooks.
It is probably safer to write an VBA that is explicitly started that iterates through a list and writes to hyperlinks. That way they can reused and there are no functions.
Regards
Andreas
I have Excel 2007 and I tried making a cell with 300 characters in A1, and another with 300 different characters in B1.
Then I made C1 = CONCATENATE(A1, B1).
I can see all of the characters from both cells. Nothing is missing or truncated and no errors were received. It looks good to me.
What makes you think that the concatenate is failing? Are you having trouble seeing your results? If your cell contains more than 1,024 characters only the first 1,024 are displayed in the cell. However they are still there and if you copy and paste them all of the characters will be copied.
Edit:
Now that you have editted your question I realize the problem is with HYPERLINK and not CONCATENATE.
The only way to get around the 255 character limit of HYPERLINK formula in Excel is to copy a hyperlink from Word and paste it into a cell in Excel. Then it can be super long. I know this is an unreasonable manual process if you have a lot of links but it seems the only way to get it into an Excel spreadsheet and yet still have it be a hyperlink that you can click on and be redirected. If you don't need it to act like a hyperlink then I would suggest rewriting your queries to return the hyperlink as its own text field and then it will be fine.
You might be out of luck. It seems that the character limit for hyperlinks in Excel is 256 as pointed out here. If you test it out yourself (I have Excel 2007, too), =HYPERLINK(REPT("a",255)) works and =HYPERLINK(REPT("a",256)) does not and throws a #VALUE! error.
Here's some VBA which uses bitly.com to shorten a URL. It is based on the bitly API documentation.
Create a free account on bitly.
Valid email address with bitly.
Get access token from bitly.
Substitute the access token in the VBA code below where it says MY_TOKEN.
Copy and paste the code in Excel's VBA.
In a cell, write the following '=Hyperlink(GetURL("some really long URL"))' without single quote ' marks. Note: Instead of passing a string to GetURL(), pass a reference to a cell which has a URL in it as text.
Public Function GetURL(longUrl As String) As String
Dim xml As Object
longUrl = URLEncode(longUrl)
Set xml = CreateObject("MSXML2.XMLHTTP.6.0")
xml.Open "GET", "https://api-ssl.bitly.com/v3/shorten?format=xml&access_token=MY_TOKEN=" & longUrl, False
xml.Send
GetURL = xml.responsetext
head = InStr(GetURL, "<url>") + 5
tail = InStr(GetURL, "</url>")
GetURL = Mid(GetURL, head, tail - head)
End Function
Function URLEncode(ByVal Text As String) As String
Dim i As Integer
Dim acode As Integer
Dim char As String
URLEncode = Text
For i = Len(URLEncode) To 1 Step -1
acode = Asc(Mid$(URLEncode, i, 1))
Select Case acode
Case 48 To 57, 65 To 90, 97 To 122
' don't touch alphanumeric chars
Case 32
' replace space with "+"
Mid$(URLEncode, i, 1) = "+"
Case Else
' replace punctuation chars with "%hex"
URLEncode = Left$(URLEncode, i - 1) & "%" & Hex$(acode) & Mid$(URLEncode, i + 1)
End Select
Next
End Function
Dunno if my answer is still useful but I had the same issue couple of days ago, the best way and proved way to do a workable hyperlink that exceeds a 255 char limit is to first split it, with CONCATENATE(), and use the cell with CONCATENATE() function in VBA.
For me it looks like:
A1 = LinkPart1
A2 = LinkPart2
A3 = LinkPart3
A5 = CONCATENATE( A1; A2; A3 )
VBA Code you need to link with A5:
Sub insertVeryLongHyperlink()
Dim curCell As Range
Dim longHyperlink As String
Set curCell = Range("A7") ' or use any cell-reference
longHyperlink = [A5]
curCell.Hyperlinks.Add Anchor:=curCell, _
Address:=longHyperlink, _
SubAddress:="", _
ScreenTip:=" - Click here to follow the hyperlink", _
TextToDisplay:="Click Here"
End Sub
Quick update for those who run into this problem - and for the support staff who suggest that the issue is perhaps too old to talk about:
Excel for Microsoft 365 MSO (Version 2203 Build 16.0.15028.20102) still has this bug.
It's a bit inexcusable, when typical URLs that you want to parameterize (a common usage in Excel) easily exceed 255, and most internet software has a default limit of 1024 characters... many even allow exceeding that by configuration.
This is a 12-year-old problem that has never been fixed.
Instead of writing
=CONCATENATE("Toto";"Tata")
Put Toto in cell Z1 (for exemple) and Tata in cell Z2 and write
=CONCATENATE(Z1;Z2)
Guys I think a URL Shortening VBA will help you. Here is one which I found today. It works like a charm:
http://www.jpsoftwaretech.com/shorten-urls-with-bit-ly-web-api-and-vba/
The Hyperlink function has a hard limit that can't be overstaped. I had a similar problem and I simply imported the Excel sheet into Open Office Calc and voila - everything worked instantly and the hyperlink that was to long previously can be now as long as I wanted it to be.
You can use the VBA Shell() routine to execute a browser and pass the URL to it on the command line passed via the Shell() call. Thus the URL can be any length supported by the shell mechanism.
Furthermore you can get this URL from any cell value by having the user double-click that cell. This value can be constructed from many cells via a single CONCATENATE() function call! That's right: just a single call. The CONCATENATE() will take a large number of parameters and will create a string well-bigger than 255 characters. You don't need to laboriously join many separate concatenations or use loads of "builder" cells. One will do!
The macro needs to be created by opening the VIEW CODE option when you right-click the tab at the bottom of the worksheet. Then write the following phenomenally short, simple and painless bit of code:
Option Explicit
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Selection.Count = 1 Then
If Left(Target.Value, 7) = "HTTP://" Then
Cancel = True
Shell ("""" + Range("Browser").Value + """" + " " + """" + Target.Value + """")
End If
End If
End Sub
Note that "Browser" is a named cell that should contain the unquoted path of your browser, be that IE, Opera, Mozilla or Chrome. You have to name the cell yourself, or change the macro to have a hard cell reference like "A2". And of course, that cell value must be a valid browser path!
Once you have all of this in place, you can double-click ANY cell that has a value starting with the text "HTTP://" and Excel will open the browser with that full value, no-matter how long it is. All you then need is to build your string in that cell and perhaps format it colour/font-wise to make it obvious that it is a hyperlink cell to be double-clicked. A textual hint nearby may also be in order!
Incidentally, an alternative to the Shell() line in the macro is:
ThisWorkbook.FollowHyperlink Address:=Target.Value
Whilst this will also process URLs bigger than 255 characters, I found that this FollowHyperlink() function causes the URL to be sent TWICE. Once by the Excel function itself (presumably to test it) and then again by the default browser that Excel opens! This may not be desirable (and wasn't in my case). This is why I ended up using the Shell() function instead.
You can create a hyperlink in Microsoft Word, and then copy it over to Excel.
For some reason, those hyperlink elements are not limited by the 255 character limit, but you won't be able to use the HYPERLINK() function.
Source
Assuming you do not have very many hyperlink URLs >255 characters, just use the Link function. The link function is available from the right-click menu. No need to go to Word or any other MSOffice application.
I know this works as I have a URL that is 281 characters long and that one works.
I only have two very long URLs in my sheet so when/if they need updating I am making a note that they must be done in the target cell vs. on my sheet of hyperlink addresses.
Working off of Andreas J's answer, you can use the below VBA code snippet to generate a column of hyperlinks from a column of plain-text URIs. Assuming column A contains the plain-text URIs and column B contains the desired link text, the following code loops through each row in Range("A:C") and generates a hyperlink in column C:
Sub createLink(a As Range, b As Range, c As Range)
Dim curCell As Range
Dim longHyperlink As String
Dim linkText As String
Set curCell = a
longHyperlink = b
linkText = c
curCell.Hyperlinks.Add Anchor:=curCell, _
Address:=longHyperlink, _
SubAddress:="", _
ScreenTip:="", _
TextToDisplay:=linkText
End Sub
Sub insertLinks()
Dim a As Range, b As Range
Set a = Range("A:C")
For Each b In a.Rows
Dim curCell As Range, longHyperlink As Range, linkText As Range
Set curCell = b.Cells().Item(1, 3)
Set longHyperlink = b.Cells().Item(1, 1)
Set linkText = b.Cells().Item(1, 2)
If longHyperlink = "" Then
Exit For
End If
createLink curCell, longHyperlink, linkText
Next
End Sub

Resources