Add Comments to Specific cells in Range. Excel VBA - vba

I am trying to add comments to specific cells in a range if they meet criteria. So I have a list in Sheet1 where the information is housed. I also have the cell value on sheet16 where I want the comment in column U, so it will say F6 in row U. I keep getting
Application-Defined or object-defined error
Any thoughts?
Thanks in Advance.
Sub Comments()
Dim rcell As Range
Sheet16.Range("C6:AR17").ClearComments
For Each rcell In Sheet1.Range("A2:A" & Sheet1.Range("A" & Sheet1.Rows.CountLarge).End(xlUp).Row)
If rcell.Offset(0, 1).Value(10) = Sheet7.Range("G1").Value(10) Then
commentvalue = rcell.Offset(0, 4).Value
Sheet16.Range("U" & rcell.Row).AddComment (commentvalue)
End If
Next rcell
End Sub

The AddComment method fails if there's already a comment on a cell. Do it like this:
Sub Comments()
Dim rcell As Range
Dim commentvalue As String
Sheet16.Range("C6:AR17").ClearComments
For Each rcell In Sheet1.Range("A2:A" & Sheet1.Range("A" & Sheet1.Rows.CountLarge).End(xlUp).row)
If rcell.Offset(0, 1).Value = Sheet7.Range("G1").Value Then
commentvalue = CStr(rcell.Offset(0, 4).Value)
With Sheet16.Range("U" & rcell.row)
.ClearComments '<=== :-)
.AddComment commentvalue
End With
End If
Next rcell
End Sub
Edit
As per #Jeeped's comment, you could want to "cumulate" comments. My assumption was that you ran the code once, then ran it again and hit the error because the first run had created the comments. Depending on what you try to achieve, you may want to systematically clear the comments in column U from rows 2 to your last row, outside of the loop, and remove the .ClearComments in the loop, in order to start clean each time. That's the simplest case. I'll let you work out the details if it's anything more complicated.

Related

Filtering depending upon the column values

I have a sheet FC, with this sheet, I have column R, S and T filled.
I would prefer to have a code, which checks if R contains "invalid" and if S and t are filled, then it should filter complete row.
I know we can use isblank function to check whether the cell is blank or not,
but I am struck how I can use a filter function with these condition .Any help will be helpful for me. I am struck how I can proceed with a vba code. Apologize me for not having a code.
You will have to somehow specify last row:
Dim lastRow, i As Long
For i = 1 To lastRow 'specify lastRow variable
If InStr(1, LCase(Range("R" & i).Value), "invalid") > 0 And Range("S" & i).Value = "" And Range("T" & i).Value = "" Then
'do work
End If
Next i
In our If condition we check three things that you asked.
Try this
Sub Demo()
Dim lastRow As Long
Dim cel As Range
With Worksheets("Sheet3") 'change Sheet3 to your data sheet
lastRow = .Cells(.Rows.Count, "R").End(xlUp).Row 'get last row in Column R
For Each cel In .Range("R5:R" & lastRow) 'loop through each cell in range R5 to lase cell in Column R
If cel.Value = "invalid" And Not IsEmpty(cel.Offset(0, 1)) And Not IsEmpty(cel.Offset(0, 2)) Then
cel.EntireRow.Hidden = True 'hide row if condition is satisfied
End If
Next cel
End With
End Sub
EDIT :
To unhide rows.
Sub UnhideRows()
Worksheets("Sheet3").Rows.Hidden = False
End Sub
Assuming Row1 is the header row and your data starts from Row2, in a helper column, place the formula given below.
This formula will return either True or False, then you may filter the helper column with either True or False as per your requirement.
=AND(R2="Invalid",S2<>"",T2<>"")
In case your header row is different, tweak the formula accordingly.
sub myfiltering()
'maybe first row always 4
firstrow=4
'last, maybe R column alaways have any entered info, so let us see what is the last
lastrow=cells(65000,18).end(xlup).row
'go ahead
for myrow=firstrow to lastrow
if cells(myrow,18)="Invalid" and cells(myrow,19)="" and cells(myrow,20)="" then
Rows(myrow).EntireRow.Hidden = True
else
Rows(myrow).EntireRow.Hidden = false
end if
next myrow
msgbox "Filter completed"
end sub
hope this will help you :)
Why you need the vba code for this problem?
Its more simple if you add a new column with if & and formula, and autofiltering within the added col.
The formula may be similar like this in the U2 cell.
=if(and(R2="invalid";S2="";T2="");"x";"")
Also set autofilter to x. :)

VBA - How to declare "Cell" variable

Apologies for the potentially very easy to answer question. I was trawling through some code on the site regarding how you search for a row and paste it in another worksheet, the code being the one below:
Sub Test()
For Each Cell In Sheets(1).Range("J:J")
If Cell.Value = "131125" Then
matchRow = Cell.Row
Rows(matchRow & ":" & matchRow).Select
Selection.Copy
Sheets("Sheet2").Select
ActiveSheet.Rows(matchRow).Select
ActiveSheet.Paste
Sheets("Sheet1").Select
End If
Next
End Sub
I was wondering what the "Cell" should be declared as, as in:
Dim Cell As ...
I'm aware that without "Option Explicit", this is irrelevant, but I'm curious nonetheless, so please do help and explain if you can.
Thank you for your help in advance :)
In your case, cell is a range, so
dim cell as range
And: Always use Option Explicit
Walking over a Range yields a Range so Dim Cell As Range
If in doubt ask VBA: msgbox TypeName(Cell)
You can use Range. They are somewhat interchangeable.
Sorry but that is horrible code and it offends the eyes. Find would be better, but just in the interest of better understanding
Sub Test()
Dim Cell as Range
For Each Cell In Sheets(1).Range("J:J")
If Cell.Value = "131125" Then
Cell.EntireRow.copy Destination:=Sheets("Sheet2").range("a" & cell.row)
'You might want to exit here if there's only one value to find with
'Exit For
End If
Next
End Sub

VBA search and copy

I'm automating an update I have to do and part of the macro I want to write needs specific text from what gets populated.
I have the following types of text in the same column for hundreds of rows:
ScreenRecording^naushi02^procr^10035
procr^10635^ScreenRecording^misby01
ScreenRecording^liw03^procr^10046
I've bold the text I need. I want to either replace the whole text with just what I need or place what I need in the next column, same row.
I had wrote something which worked for 60 or so lines before I realised that there are variations in the format. For the main, it's all the same which is why I didn't realise at first and I've spent a lot of wasted time writing something that is now useless... so I'm asking for expert help please.
Once I've got what I need from the first row, I need to move down until the last entry repeating.
I had some code which obviously didn't work fully.
I have thought about using the text 'ScreenRecording' in a search along with the special character which I can't find on my keyboard and then trying to copy all text from that point upto and including the 2nd numerical character. I don't know how to do this, if it would work or even if it's a good idea but because I've spent so much time trying to figure it out, I need some help please.
Thanks in advance
If you always want to return the value after the word 'ScreenRecording`, you can use the following function to do so.
Include it in a SubRoutine to replace in place if needed:
Function SplitScreenRecording(sInput As String) As String
Dim a As Variant
Const SDELIM As String = "^"
Const LOOKUP_VAL As String = "ScreenRecording"
a = Split(sInput, SDELIM)
If IsError(Application.Match(LOOKUP_VAL, a, 0)) Then
SplitScreenRecording = CVErr(2042)
Else
SplitScreenRecording = a(Application.Match(LOOKUP_VAL, a, 0))
End If
End Function
Sub ReplaceInPlace()
Dim rReplace As Range
Dim rng As Range
Set rReplace = Range("A1:A3")
For Each rng In rReplace
rng.Value = SplitScreenRecording(rng.Value)
Next rng
End Sub
if you want to replace:
Sub main2()
Dim key As String
Dim replacementStrng As String
key = "ScreenRecording"
replacementStrng = "AAA"
With Worksheets("mysheet01").columns("A") '<--| change "mysheet01" and "A" to your actual sheet name and column to filter
.Replace what:=key & "^*^", replacement:=key & "^" & replacementStrng & " ^ ", LookAt:=xlPart
.Replace what:="^" & key & "^*", replacement:="^" & key & "^" & replacementStrng, LookAt:=xlPart
End With
End Sub
while if you want to place what you need in the next column:
Sub main()
Dim myRng As Range
Set myRng = GetRange(Worksheets("mysheet01").columns("A"), "ScreenRecording^") '<--| change "mysheet01" and "A" to your actual sheet name and column to filter
myRng.Offset(, 1) = "value that I need to place in next row" '<--| change the right part of the assignment to what you need
End Sub
Function GetRange(rng As Range, key As String) As Range
With rng
.AutoFilter Field:=1, Criteria1:="*" & key & "*" '<--| apply current filtering
If Application.WorksheetFunction.Subtotal(103, .Cells) > 0 Then '<--| if there are visible cells other than the "header" one
With .SpecialCells(xlCellTypeConstants)
If InStr(.SpecialCells(xlCellTypeVisible).Cells(1, 1), key & "^") > 0 Then
Set GetRange = .SpecialCells(xlCellTypeVisible) '<--|select all visible cells
Else
Set GetRange = .Resize(.Parent.Cells(.Parent.Rows.Count, .Column).End(xlUp).row - 1).Offset(1).SpecialCells(xlCellTypeVisible) '<--|select visible rows other than the first ("headers") one
End If
End With
End If
.Parent.AutoFilterMode = False '<--| remove drop-down arrows
End With
End Function

Excel userform deleting entire row not just intended selction

I have a userform that has a drop down box in which a person can select a record to have deleted off a list.
The code below is deleting the ENTIRE ROW. I do not want that. I just want the cells between A:E cleared on my spreadsheet.
I am not sure how else to describe this so I apologize in advance. Here is the code:
Private Sub CheckBox1_Click()
End Sub
Private Sub CommandButton1_Click()
Dim lRw As Long
ActiveWorkbook.Sheets("RAWDATA").Visible = xlSheetVisible
'get the row number. add 2 because ListIndex starts at one
lRw = Me.ComboBox1.ListIndex + 2
ActiveWorkbook.Sheets("RAWDATA").Select
Cells(lRw, 1).EntireRow.ClearContents
ActiveWorkbook.Sheets("RAWDATA").Visible = xlSheetHidden
End Sub
Private Sub CommandButton2_Click()
ComboBox1.Value = ""
ComboBox1.Clear
ComboBox1.Clear
Unload Me
End Sub
Private Sub UserForm_Initialize()
'assumes data starts in A1 and has a header row
Me.ComboBox1.List = ActiveWorkbook.Sheets("RAWDATA").Cells(1, 2).CurrentRegion.Offset(1, 2).Value
End Sub
side note: You don't need to select the cells to manipulate the contents in vba.
Check out this link to explain that concept in more detail:
how-to-avoid-using-select-in-excel-vba-macros
This is the problem code. You are clearing the entire row, using ".EntireRow.ClearContents"
ActiveWorkbook.Sheets("RAWDATA").Select
Cells(lRw, 1).EntireRow.ClearContents
ActiveWorkbook.Sheets("RAWDATA").Visible = xlSheetHidden
Here are three solutions. Both should give you some insight into how the .Cells(row,col) idea works while using a loop. You are using a variable to control the row number, and the same concept can be applied to the column. Even though it's just 5 columns. It might be 50 for another project. So you can loop through them using a "For Loop" This is my preferred method.
If you want to get loopy, try something like this. Use a Variable for the Column
For lCol = 1 To 5
Sheets("RAWDATA").Cells(lRw, lCol).ClearContents
Next lCol
You can do one cell at a time Directly coding the column number:
Sheets("RAWDATA").Cells(lRw, 1).ClearContents
Sheets("RAWDATA").Cells(lRw, 2).ClearContents
Sheets("RAWDATA").Cells(lRw, 3).ClearContents
Sheets("RAWDATA").Cells(lRw, 4).ClearContents
Sheets("RAWDATA").Cells(lRw, 5).ClearContents
You can do one cell at a time Directly coding the column LETTER:
Sheets("RAWDATA").Cells(lRw, "A").ClearContents
Sheets("RAWDATA").Cells(lRw, "B").ClearContents
Sheets("RAWDATA").Cells(lRw, "C").ClearContents
Sheets("RAWDATA").Cells(lRw, "D").ClearContents
Sheets("RAWDATA").Cells(lRw, "E").ClearContents
edit: added some explanation and link
The cells(lRw, 1).EntireRow.ClearContents is your issue. The EntireRow function selects the row which is pointed to by cells(lRw, 1). The .ClearContents function clears what's selected. You should replace it with something like:
Range("A" & <the row number> & ":J" & <the row number>).clearcontents
Your variable lRw is supposed to hold the value of the row in which the selected project is located, correct? If so, then:
Range("A" & lRw & ":J" & lRw ).clearcontents
should work. You can change the column letters to whatever you'd like to clear.
I think PJ Rosenburg's solutions are bit impractical, but I agree with the fact that you should shy away from using the .select function. You can do everything you need to do without using it. You'll write much better code once you understand this concept. In fact, here's a rewrite of your commandButton1_click that should do the exact same thing, but with less code and is easier to read.
Private Sub CommandButton1_Click()
Dim lRw As Long
lRw = Me.ComboBox1.ListIndex + 2
with ActiveWorkbook.Sheets("RAWDATA")
.Visible = xlSheetVisible
.Range("A" & lRw & ":J" & lRw ).clearcontents
.Visible = xlSheetHidden
end with
end sub
Notice a couple of things:
No .select
Moving the assignment statement
The addition of the With/End With statements
Anyway, I hope this helps and better explains what I was trying to say earlier.

Copy a dynamic range of values, possibly with the help of Vlookup or Match

Every year a row of data is added to my work sheet at row 14 (the years are listed in descending order). I'm trying to copy a range that starts at C14 and ends somewhere in column C based on the value '1990' in column A. I thought vlookup may be able to solve this but perhaps not. I'm definitely open to any other methods. Here is the code I was trying to get to work.
Sub Figure11()
iRow = Cells(14, 1).End(xlDown).Row
Sheets("BCW").Range("C14:=Vlookup(1990, A14:C" & iRow & ", 3,FALSE)").Copy
Worksheets("Figure1-1").Range("B3").PasteSpecial xlPasteValues
End Sub
Thanks in advance for any help.
Best regards,
Assuming the year 1990 appears only once in column A:
Sub Figure11()
Dim yr1990 As Variant
Dim rw As Integer
Sheets("BCW").Activate
Set yr1990 = Columns(1).Find(what:=1990, lookat:=xlWhole)
If yr1990 Is Nothing Then
Debug.Print "year 1990 not found"
Exit Sub
Else:
rw = Cells.Find(what:=1990, lookat:=xlWhole).Row
End If
Range("C14", Cells(rw, 3)).Copy
Worksheets("Figure1-1").Range("B3").PasteSpecial xlPasteValues
End Sub