Cataloging Problematic Cells by Hyperlink Copying - vba

I'm trying to flag problematic cells and link the cell hyperlink to another cell to review later. Here is my code. Not all of the code is visible. I Called "i" and "j" as long. The error occurs on newLink = Range("AL" & i).Hyperlinks(1).Address claiming that it is "out of range." I think this means that it is calling something that doesn't exist, but to be honest i'm not sure.
If Range("AK" & i).Value = "On" Then
If Range("AL" & i).Value = 0 And Range("AM" & i).Value = 0 Then
Range("AL" & i, "AM" & i).Interior.ColorIndex = 6
'Cells("AL" & i) = H.Address'
ErrorCount = ErrorCount + 1
Dim newLink As String
newLink = Range("AL" & i).Hyperlinks(1).Address
Range("IV" & j).Hyperlinks.Add anchor:=Range("IV" & j), Address:=Range("IV" & j)
Range("IV" & j).Hyperlinks(1).Address = newLink
j = j + 1
End If

If there is no hyperlink attached to a cell then Range("foo").Hyperlinks.Count will return 0 and therefore you will get an 'Out of range' error.
You just need to wrap the newLink = ... statement in an If to check if there is already a hyperlink there. E.g.
If Range("AL" & i).Hyperlinks.Count = 1 Then
newLink = Range("AL" & i).Hyperlinks(1).Address
Else
'what else will you do?
End If

Related

Excel VBA Runtime error 1004: Application defined or object defined error

I've scoured the internet for an answer to my problem. I am writing some code to input a formula into certain cells on a worksheet and despite very similar code working perfectly earlier in the macro, this section of code will not work with giving me the runtime error 1004: application-defined or object-defined error.
I have tried moving my code into a new workbook but the problem was not solved and I just can't see why it won't work.
The code below is where I define the sheets I am using
Sub InputFormulae()
Dim wksht As Worksheet
Dim wksht1 As Worksheet
Dim wksht2 As Worksheet
Dim wksht3 As Worksheet
Dim wksht4 As Worksheet
Dim wksht5 As Worksheet
Set wksht = ThisWorkbook.Worksheets("Coils same day remove & insert")
Set wksht1 = ThisWorkbook.Worksheets("Implants same day remove&insert")
Set wksht2 = ThisWorkbook.Worksheets("Implant inserted NO Removal")
Set wksht3 = ThisWorkbook.Worksheets("Implant inserted AND removed")
Set wksht4 = ThisWorkbook.Worksheets("Coil inserted NO removal")
Set wksht5 = ThisWorkbook.Worksheets("Coil inserted AND removed")
The code below is a part of the macro that is working
wksht.Activate
With wksht
i = Range("A" & Cells.Rows.Count).End(xlUp).Row
Do Until i = 1
If .Cells(i, 1) <> "" Then
Cells(i, 9).Formula = "=IF(A" & i & "=A" & i + 1 & ",IF(C" & i & "=C" & i + 1 & ",(H" & i & "-C" & i & "),(F" & i + 1 & "-C" & i & ")),IF(A" & i & "=A" & i - 1 & ",IF(C" & i & "=C" & i - 1 & ",(H" & i & "-C" & i & "),(H" & i & "-C" & i & ")),(H" & i & "-C" & i & ")))"
End If
i = i - 1
Loop
End With
And the code below here is the part that is not working
wksht3.Activate
With wksht3
i = Range("A" & Cells.Rows.Count).End(xlUp).Row
Do Until i = 1
If .Cells(i, 1) <> "" And .Cells(i, 3) <> "" And .Cells(i, 6) <> "" Then
Cells(i, 9).Formula = "=F" & i & "-C" & i & ")"
Else: Cells(i, 9).Value = "0"
End If
i = i - 1
Loop
End With
When I debug the code it highlights the Cells(i, 9).Formula = "=F" & i & "-C" & i & ")" line
Thanks for your time
=F10-C10)
is not a valid formula so you get a 1004
The error you get is because VBA does not understand "=F" & i & "-C" & i & ")". As far as it is a string, the easiest way to debug is to write either:
debug.print "=F" & i & "-C" & i & ")" on the line above and to see the immediate window for the value
or
MsgBox "=F" & i & "-C" & i & ")" on the line above and to see the string in a MsgBox.
Based on the result you would know how to continue.
Start with putting a period in front of every Range and Cells within a With ... End With.
Brackets come in pairs.
Don't turn real numbers into text-that-looks-like-a-number.
wksht3.Activate '<~~ totally unnecessary to use a With ... End With
With wksht3
i = .Range("A" & .Cells.Rows.Count).End(xlUp).Row
Do Until i = 1
If .Cells(i, 1) <> "" And .Cells(i, 3) <> "" And .Cells(i, 6) <> "" Then
.Cells(i, 9).Formula = "=F" & i & "-C" & i
Else
.Cells(i, 9).Value = 0
End If
i = i - 1
Loop
End With
FWIW, you could also just have your formula do the tests too:
With wksht3
i = Range("A" & Cells.Rows.Count).End(xlUp).Row
.Range("I1:I" & i).FormulaR1C1 = "=IF(OR(RC1="""",RC3="""",RC6=""""),0,RC6-RC3)"
End With

Code Skipping Second Cell, Not Supposed To

This code is a part of bigger code that takes words from a listbox and places into another listbox, which with this code separates the words in the listbox and establishes into words that are able to be inserted into a cell, for some reason second strsplt is not showing, everything else is working very well, it's just this one, I need help with and there is no error that is thrown out. I've looked it over with F8 and breakpoints and the problem seems to be with
If ii < .ColumnCount - 1 Then
str = str & .List(i, ii) & vbCrLf
Else
str = str & .List(i, ii)
End If
The Whole Code:
With Me.selecteditems
ThisWorkbook.Sheets(9).Range("A:B").ClearContents
For i = 0 To .ListCount - 1
If .Selected(i) Then
found = True
For ii = 0 To .ColumnCount - 1
ReDim strsplt(0 To i)
If str = "" Then
str = .List(i, ii) & vbCrLf
Else
If ii < .ColumnCount - 1 Then
str = str & .List(i, ii) & vbCrLf
Else
str = str & .List(i, ii)
End If
End If
Next ii
message = "How much" & vbCrLf & str & "?" & vbCrLf
title = "Amount"
defaultval = "1"
quantity = InputBox(message, title, defaultval)
strsplt = Split(str, "*")
End If
'On Error Resume Next
With ThisWorkbook.Sheets(9)
.Range("A" & (i + 1)).Value = strsplt(i)
.Range("B" & (i + 1)).Value = quantity
End With
'On Error GoTo 0
Next i
End With
EDIT: The way it looks like using debug.print str
item1
item2 item3 item4 ...
Try a bit brute forcing like this:
If ii < .ColumnCount - 1 Then
str = str & .List(i+1, ii) & vbCrLf
Else
str = str & .List(i+1, ii)
End If
I have changed i to i+1 in your code.
Then debug again. If it does not work, try i-1, ii+1, ii-1. One of these will work and it may give an out of range error. Then fix the array length and have fun.

Fill a column from a concatenate range

What I have this far is below.
Range("F4").Value = Range("D4").Value & " x " & Range("E4")
This is creating a concatenate in Column F for me. This is working fine for the individual cell but I would like this to continue concatenating down until it hits an empty cell.
I have tried looping without success.
below is an image of the sheet
Set Concat= Rows(4)
concatstring =""
For i = 1 To Concat.Cells.Count
If Concat.Cells(i).Text <> "" Then
Concatstring = concatstring & " x " & Concat.Cells(i).Text
Else
Exit for
End If
Next
Concat.cells(I).text = concatstring
This should do it. Let me know if you still have problem.
Try this...
i=4
Do while(Range("D" & i).Value<> "")
Range("F" & i).Value = Range("D" & i).Value & " x " & Range("E" & i)
Loop

Excel VBA: how to apply code when it finds text in a column

I have the following code, modified by #FreeMan from one of my previous questions. I want to find the text "Hours" in any row in the worksheet. Then, apply the code to the column containing that text. This code is supposed to do that, but it does not work for me for some reason. I would really appreciate your help with this. Thank you in advance.
Sub CeldasinInfo()
Dim i As Long, r As Range, coltoSearch As String
Dim Result as String
Dim ErrCount as integer
ErrCount = 0
coltoSearch = "A"
coltoSearch = Range("1:1").find(What:="Hours", LookIn:=xlValues, LookAt:=xlWhole).Column
Result = "No Value in:" & vbcrlf
For i = 1 To Range(coltoSearch & Rows.Count).End(xlUp).Row
Set r = Range(coltoSearch & i)
If Len(r.Value) = 0 Then
r.Interior.ColorIndex = 3 ' Red
r.Select
MsgBox "No Value, in " & r.Address
Result = Result & r.Address & vbcrlf
ErrCount = ErrCount + 1
if ErrCount Mod 10 = 0 then 'change to 15 or 20 or whatever works well
MsgBox Result
Result = "No Value in:" & vbcrlf
End If
Sheets("Results").Range("A" & Sheets("Results").Range("A" & Rows.Count).End(xlUp).Row).Offset(1, 0).Formula = r.Address
End If
Next
If ErrCount > 0 then
MsgBox "There were " & ErrCount & " errors detected." & vbcrlf & result
else
MsgBox "No errors detected"
End If
End Sub
You need to change these two lines of code:
For i = 1 To Range(coltoSearch & Rows.Count).End(xlUp).Row
Set r = Range(coltoSearch & i)
to:
For i = 1 To Cells(Rows.Count, coltoSearch).End(xlUp).Row
Set r = Cells(i, coltoSearch)
Remove line: coltoSearch = "A"
coltoSearch should be an integer.

VBA Text Array - Scan two columns for array string match rather than one

I have some code which is designed to scan Columns F & G for occurrences of words found in an array, the array containing text found in Column J. If it finds occurrences in either Column F or Column G, it will copy and paste the terms into the corresponding columns.
Column J contains free text from a field in SAP. The field is free text so it could be "Kerry John Pub Expenses" or "CATS O/H Kerry John", or even "CATS John Kerry O/H". There is no data entry standard for this field; this is what makes this task difficult .
Column F and Column G contains first names and last names. The code makes an assumption, if it finds an entry in column F or G that matches an entry in the txt array, it will copy and paste that entry.
During testing, the code proved not sufficient to match the outcomes which I was looking for, and the solution to this problem would be to match text in Columns F and G concurrently for two matching words rather than doing them in separate intervals.
I would like some suggestions as to how this code could be re-written to achieve this result.
Example of successful code run
Here we have 4 rows of data, John Citizen is located in Row 3, therefore the blank cells in Columns F and G, Row 2 can be populated with his first and last name.
The problem
Because I have two rows that contain Kerry Citizen and John Kerry, the row is populated with Kerry Kerry as a result, where the entry should be "John" in Column F and "Kerry" in Column G
Code starts here
Sub arraycolumnmatch()
Dim txtArray As Variant, T As Variant
Dim I As Long, J As Long
For I = 2 To Range("E50000").End(xlUp).row
typ = Range("F" & I).Value
If typ = "" Then
txt = Range("J" & I).Value
txtArray = Split(txt, " ")
For Each T In txtArray
For J = 2 To Range("F50000").End(xlUp).row
If Range("F" & J).Value = T Then
match_txt = T
Range("F" & I).Value = match_txt
End If
Next J
Next T
For Each T In txtArray
For J = 2 To Range("G50000").End(xlUp).row
If Range("G" & J).Value = T Then
match_txt = T
Range("G" & I).Value = match_txt
End If
Next J
Next T
End If
Next I
End Sub
You can simplify your code greatly, and make it work, like this:
typ = Range("F" & I).Value
If typ = "" Then
txt = Range("J" & I).Value
matchFound = False
For J = 2 To Range("G50000").End(xlUp).Row
If InStr(txt, Range("F" & J).Value) <> 0 _
And InStr(txt, Range("G" & J).Value) _
And Not (IsEmpty(Range("F" & J).Value)) _
And Not (IsEmpty(Range("G" & J).Value)) Then
'Both names match. Copy them.
Range("F" & I).Value = Range("F" & J).Value
Range("G" & I).Value = Range("G" & J).Value
matchFound = True
Exit For ' look no further.
End If
Next J
If Not matchFound Then MsgBox "No match found for: " & txt
End If
Tested, works for me.
The Code below runs for every first name on the list but only adds the name if both names match.
Sub arraycolumnmatch()
Dim txtArray As Variant, t As Variant
Dim I As Long, J As Long
For I = 2 To Range("G50000").End(xlUp).Row
typ = Range("F" & I).Value
If typ = "" And Not Range("J" & I).Value = Empty Then
txt = Range("J" & I).Value
txtArray = Split(txt, " ")
For Each word In txtArray
If Not word = "" Then
Set findtext = Range("F:F").Find _
(what:=(word), LookIn:=xlValues)
stoploop = False
loopcnt = 0
Do While Not findtext Is Nothing And stoploop = False And loopcnt < 21
loopcnt = loopcnt + 1
If InStr(txt, Range("F" & findtext.Row).Value) <> 0 _
And InStr(txt, Range("G" & findtext.Row).Value) Then
'Both names match. Copy them.
Range("F" & I).Value = Range("F" & findtext.Row).Value
Range("G" & I).Value = Range("G" & findtext.Row).Value
stoploop = True
Exit For ' look no further.
Else
Set findtext = Range("F" & findtext.Row & ":F" & 50000).Find _
(what:=(word), LookIn:=xlValues)
End If
Loop
End If
Next word
If Not stoploop Then MsgBox "No match found for: " & txt
End If
Next I
End Sub
Edit: Did an integration of #Jean InStr and a Find in Range which would allow for less loop time and a double match find.
I have had to stick with my original syntax, answer is below. Not the most efficient way of reaching the result, but it works
Sub arraycolumnmatch()
Dim txtArray As Variant, T As Variant
Dim I As Long, J As Long
For I = 2 To Range("E50000").End(xlUp).row
typ = Range("F" & I).Value
If typ = "" Then
txt = Range("J" & I).Value
txtArray = Split(txt, " ")
For Each T In txtArray
For J = 2 To Range("G50000").End(xlUp).row
If Range("G" & J).Value = T Then
match_txt = T
Range("G" & I).Value = match_txt
Exit For
End If
Next J
Next T
For Each T In txtArray
For J = 2 To Range("F50000").End(xlUp).row
If Range("F" & J).Value = T Then
match_txt = T
If Not Range("G" & I).Value = T Then
Range("F" & I).Value = match_txt
Exit For
End If
End If
Next J
Next T
End If
Next I