Looking for either a workaround or some idea on how I can use the code excerpt below, but skip column A.
Basically, I'm using
.EntireRow(a.Row).Interior.Color = color
to highlight rows based on a userform selection, but I need to skip column A as it has headers that have their own highlighting.
Any ideas?
If ToggleButton3.Value = True Then
On Error Resume Next
For iRow = 1 To 15
If Sheets("Prop" & iRow).Visible <> xlSheetVisible Then
Else
With Sheets("Prop" & iRow).Range("$E$1:$E$157")
Set a = .Find(SlctdPAX, LookIn:=xlValues, LookAt:=xlWhole)
.EntireRow(a.Row).Interior.Color = RGB(255, 255, 102) 'yellow
End With
End If
Next iRow
ElseIf ToggleButton1.Value = True Then
On Error Resume Next
For iRow = 1 To 15
If Sheets("Prop" & iRow).Visible <> xlSheetVisible Then
Else
With Sheets("Prop" & iRow).Range("$E$1:$E$157")
Set a = .Find(SlctdPAX, LookIn:=xlValues, LookAt:=xlWhole)
.EntireRow(a.Row).Interior.Color = RGB(255, 0, 0) 'red
End With
End If
Next iRow
ElseIf ToggleButton4.Value = True Then
On Error Resume Next
For iRow = 1 To 15
If Sheets("Prop" & iRow).Visible <> xlSheetVisible Then
Else
With Sheets("Prop" & iRow).Range("$E$1:$E$157")
Set a = .Find(SlctdPAX, LookIn:=xlValues, LookAt:=xlWhole)
.EntireRow(a.Row).Interior.Color = xlNone 'no fill
End With
End If
Next iRow
ElseIf ToggleButton2.Value = True Then
On Error Resume Next
For iRow = 1 To 15
If Sheets("Prop" & iRow).Visible <> xlSheetVisible Then
Else
With Sheets("Prop" & iRow).Range("$E$1:$E$157")
Set a = .Find(SlctdPAX, LookIn:=xlValues, LookAt:=xlWhole)
.EntireRow(a.Row).Interior.Color = RGB(128, 255, 0) 'green
End With
End If
Next iRow
Else
End If
Lets say a is a single cell.
With regards to exclude highlighting column A,
to highlight entire row of a, do:
a.EntireRow.Resize(, Columns.Count - 1).Offset(, 1).Interior.Color
to highlight multiple rows staked together below a, e.g. 5 rows, do:
a.EntireRow.Resize(5, Columns.Count - 1).Offset(, 1).Interior.Color
to highlight multiple rows which are not staked together, e.g. entire rows of [E1], [E3], [E5], do:
Intersect(Union([E1], [E3], [E5]).EntireRow, Cells.Resize(, Columns.Count - 1).Offset(, 1))
FYI, just tested that Union([E1], [E3], [E5]).EntireRow.Resize() is not allowed.
Hope this helps.
With ThisWorkbook.Sheets("Prop" & iRow)
Set a = .Range("$E$1:$E$157").Find(SlctdPAX, LookIn:=xlValues, LookAt:=xlWhole)
a.EntireRow.Resize(1, .Cells(a.row, .Columns.Count - 1).column).Offset(, 1).Interior.Color = RGB(255, 0, 0) 'red
End With
which is quite much whar KS Sheon has already posted.
but I'm afraid his code, being inside With Sheets("Prop" & iRow).Range("$E$1:$E$157") block , would color all rows from 1 to 157.
moreover Columns.Count would count the number of columns of the active sheet, which may not be the one wanted
Related
I am trying to add value from column D only but if search value is from D, E or F column the offset function adds item from subsequent column. Only column D value needs to be added to the listbox.
The Do loop searches fetches the value but not sure how to fetch values only from specific column.
Please help:
If Len(txtSearchItem.Value) > 3 Then
Dim rFind, rng, rngdb As Range
Dim i, j As Integer
Dim strItem As String
With ActiveWorkbook.Sheets("DB").Columns("C:F")
Set rFind = .Find(What:=Me.txtSearchItem.Value, lookat:=xlPart, MatchCase:=False, SearchFormat:=False)
Me.lstItem.Clear
If Not rFind Is Nothing Then
i = rFind.Row 'rFind.Column & ", Row: " & rFind.Row
Me.lblDBDescription = xlshdb.Cells(i, 3).Value
'Me.txtItem.Value = xlshdb.Cells(i, 4).Value
'*****Show the Item list's in list box ****
With xlshdb.Range("C:C")
Set rng = .Cells(LRow)
End With
Set rngdb = xlshdb.Range("C:F").Find(What:=Me.txtSearchItem.Value, After:=rng, LookIn:=xlValues, lookat:=xlPart, searchorder:=xlByRows, MatchCase:=False)
If Not rngdb Is Nothing Then
FirstAddr = rngdb.Address
Do Until rngdb Is Nothing
'Debug.Print rngdb.Address
Set rngdb = xlshdb.Range("C:F").FindNext(After:=rngdb)
Me.lstItem.AddItem rngdb.Offset(0, 1)
If rngdb.Address = FirstAddr Then
Exit Do
End If
Loop
If Me.lstItem.ListCount > 1 Then
Me.txtItem.Visible = False
Me.lstItem.Visible = True
Me.lstItem.Selected(0) = True
Else
Me.lstItem.Visible = False
Me.txtItem.Visible = True
Me.txtItem.Value = xlshdb.Cells(i, 4).Value
End If
Else
Me.lstItem.Clear
Me.lstItem.Visible = False
Me.txtItem.Visible = True
Me.txtItem.Value = xlshdb.Cells(i, 4).Value
End If
Else
Me.lstItem.Clear
Me.lstItem.Visible = False
Me.txtItem.Visible = True
Me.lblDBDescription = ""
Me.txtItem = ""
End If
End With
End if
Will just make an answer so there is one.
Simply change the line:
Me.lstItem.AddItem rngdb.Offset(0, 1)
To:
Me.lstItem.AddItem .cells(rngdb.row, 4)
We grab the row value of the found cell and use it as our row in the .Cells range.
I have some data in sheet1 as a table (named Table1), and I am changing the font color for some headers based on name and I want to only hide the header if its font color is black so keep orange and white un-hide. When I open the original worksheet, column headers has font color of white.
Right now when I run my codes, there are no error, but I only see columns with headers of orange font color which is not correct. For some reason when I convert my data into range, it works but I don't want to use unlist and re-create a table for the data.
Sub Data_Formatting()
Dim i, j, k As Long
Range(Range("A1"), Range("A1").End(xlToRight)).Interior.Color = RGB(79, 129, 189)
Last = Cells(1, Columns.Count).End(xlToLeft).Column
For i = Last To 1 Step -1
If (Cells(1, i).Value) = "System" Then
Cells(1, i).Font.Color = RGB(0, 0, 0)
End If
Next i
For j = Last To 1 Step -1
If (Cells(1, j).Value) = "AOB" Then
Cells(1, j).Font.Color = RGB(255, 153, 0)
End If
Next j
Range("A:D").Columns.AutoFit
Dim l As Long
Dim lColumn As Long
Dim ws As Worksheet: Set ws = ActiveSheet
'Last column
lColumn = ws.Cells(1, Columns.Count).End(xlToLeft).Column
For l = 1 To lColumn
If Cells(1, l).Font.Color = RGB(0, 0, 0) Then
Cells(1, l).EntireColumn.Hidden = True
Else
Cells(1, l).EntireColumn.Hidden = False
End If
Next
End Sub
You only need to loop once here and do all of your logic in that one loop. The way you are doing it now is looping three times over the same set of columns just to perform slightly different actions.
Sub Data_Formatting()
Dim i as Long
'set the background to blue
Range(Range("A1"), Range("A1").End(xlToRight)).Interior.Color = RGB(79, 129, 189)
'Find last cell
Last = Cells(1, Columns.Count).End(xlToLeft).Column
'autofit before hiding
Range("A:D").Columns.AutoFit
'loop once
For i = Last To 1 Step -1
If (Cells(1, i).Value) = "System" Then
Cells(1, i).Font.Color = RGB(0, 0, 0) 'black
Columns(i).Hidden = True
ElseIf Cells(1, j).Value = "AOB" Then
Cells(1, j).Font.Color = RGB(255, 153, 0) 'orange
Columns(i).Hidden = False
End If
Next i
End Sub
With this change we don't have to bother detecting the cell color since you are setting that based on the value in the same loop. Test the value, set the color, and hide it all in one shot.
I'm trying to figure out how to implement a macro to get results as follows:
I have no idea how to do it. This is what I've done so far.
I want to have additional column "Action" and if value in column "State" for e.g R1 is empty or "no_fix" then QM (green) else QA (red).
I have data with ~5000 rows
Hi, thanks it works as I expected. However, after testing of my data it turned out that I need to check additional conditions.
1.Additionally for QM and QA:
check in column G if value = "ST"
check in column H if value = 0
2.QA
check in column C if value = "No TC for LM" check in column D if
value = "no state" check in column E if value = "No IPIS" if any of
values = true then QA
Sub MergeSameCell()
'area
Dim Rng As Range, xCell As Range, Test As Range
Dim Rng1 As Range
Dim xRows As Integer
xTitleId = "Merge duplicated cells"
Set WorkRng = Application.Selection
Set WorkRng = Application.InputBox("Range", xTitleId, WorkRng.Address,
Type:=8)
Application.ScreenUpdating = False
Application.DisplayAlerts = False
xRows = WorkRng.Rows.Count
For Each Rng In WorkRng.Columns
For i = 1 To xRows - 1
For j = i + 1 To xRows
'If Rng.Cells(i, 1).Value > 0 And Rng.Cells(j, 1).Value > 0 Then
If Rng.Cells(i, 1).Value <> Rng.Cells(j, 1).Value Then
Exit For
End If
Next
'WorkRng.Parent.Range(Rng.Cells(i, 1), Rng.Cells(j - 1, 1)).Merge
'Text = WorkRng.Parent.Range(Rng.Cells(i, 1), Rng.Cells(j - 1, 1))
i = j - 1
For Each Rng1 In Range(Rng.Cells(i, 1), Rng.Cells(j - 1, 1))
For Z = 1 To 13
'MsgBox i
'MsgBox j
If Rng1.Offset(Z, 1).Value = "no_to_fix" Or Rng1.Offset(Z,
1).Value
= "" Then
'WorkRng.Parent.Range(Rng.Cells(i, 1), Rng.Cells(j - 1,
1)).Merge
Rng1.Cells.Offset(Z, 1).Interior.ColorIndex = 37
'MsgBox "supcio"
End If
Next
Next
Next
Next
WorkRng.VerticalAlignment = xlCenter
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
The following code will do the merging you want and, if I understand what you mean by the second part of the question, will set the first column to be either "QM" (if the fourth column is never anything other than blank or "no_fix") or "QA".
Code assumes you will use the InputBox to select a range containing four columns, the first being the column that will contain "QM" or "QA", the second being the column that is your "Req" column, and the fourth being your "State" column. (The code never looks at what is in the third column.)
Sub MergeSameCell()
Dim WorkRng As Range
xTitleId = "Merge duplicated cells"
Set WorkRng = Selection
Set WorkRng = Application.InputBox("Range", xTitleId, WorkRng.Address, Type:=8)
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim startRow As Long
Dim endRow As Long
Dim r As Long
Dim isQM As Boolean
'Use "startRow" to keep track of the start of each block
startRow = 1
With WorkRng
'Loop through each row in the selected range
For endRow = 1 To .Rows.Count
If .Cells(endRow + 1, 2).Value <> .Cells(startRow, 2).Value Then
'Only do something if the next row has a different value in the second column
'merge rows in the first and second columns
.Worksheet.Range(.Cells(startRow, 1), .Cells(endRow, 1)).MergeCells = True
.Worksheet.Range(.Cells(startRow, 2), .Cells(endRow, 2)).MergeCells = True
'Check for "no_fix" or blank
isQM = True ' Assume it is a "QM" until we determine it isn't
For r = startRow To endRow
If .Cells(r, 4).Value <> "" And .Cells(r, 4).Value <> "no_fix" Then
'If the 4th column is not blank and is not "no_fix", it isn't a "QM"
isQM = False
Exit For
End If
Next
'Update column 1 to show QM or QA
With .Cells(startRow, 1)
If isQM Then
.Value = "QM"
.Interior.Color = vbGreen
Else
.Value = "QA"
.Interior.Color = vbRed
End If
End With
'Point to start of next block
startRow = endRow + 1
End If
Next
End With
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
I'm updating and populating a combobox named textoControles after updating another combobox named textoCausas. The first combobox textoControles upadtes itself with its change.
Now, I'm getting error '5' in this scenario:
If I have the table ActiveSheet.Name with no data (empty) and enter data into combobox textoCausas, and then enter a character (just entering any character) on textoCausas, then the error '5' stops the macro.
But, if the table ActiveSheet.Name has any data in the first column and I enter data into textoCausas no error stops the macro.
I need some help to solve this error. Thanks!
Private Sub textoCausas_AfterUpdate()
Dim ws As Worksheet, controles As Range, planes As Range, utlimafila As Double, numeroCausa As Double, C As Range
Set ws = Worksheets(ActiveSheet.Name)
ultimafila = ws.ListObjects(ActiveSheet.Name).Range.Columns(11).Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
If ultimafila <> 8 Then
With Me.textoControles
.Clear
If Not IsError(Application.Match(Me.textoCausas.Value, ws.ListObjects(ActiveSheet.Name).ListColumns(1).DataBodyRange, 0)) Then
Set C = ws.ListObjects(ActiveSheet.Name).ListColumns(1).DataBodyRange.Find(textoCausas.Value, LookIn:=xlValues, lookat:=xlWhole)
index = C.Row
numeroCausa = ws.Cells(index, 11)
For Each controles In ws.ListObjects(ActiveSheet.Name).ListColumns(2).DataBodyRange
If controles.Columns(10) = numeroCausa Then
If controles.Value <> Empty Then
.AddItem controles.Value
.List(.ListCount - 1, 1) = controles.Offset(0, 1).Value
End If
End If
Next controles
End If
End With
With Me.textoPlanes
.Clear
If Not IsError(Application.Match(Me.textoCausas.Value, ws.ListObjects(ActiveSheet.Name).ListColumns(1).DataBodyRange, 0)) Then
Set C = ws.ListObjects(ActiveSheet.Name).ListColumns(1).DataBodyRange.Find(textoCausas.Value, LookIn:=xlValues, lookat:=xlWhole)
index = C.Row
numeroCausa = ws.Cells(index, 11)
For Each planes In ws.ListObjects(ActiveSheet.Name).ListColumns(6).DataBodyRange
If planes.Columns(6) = numeroCausa Then
If planes.Value <> Empty Then
.AddItem planes.Value
.List(.ListCount - 1, 1) = planes.Offset(0, 1).Value
End If
End If
Next planes
End If
End With
End If
Me.textoControles = Null
Me.textoPlanes = Null
End Sub
Private Sub textoControles_Change()
Dim ws As Worksheet, C As Range, C2 As Range
Set ws = Worksheets(ActiveSheet.Name)
Me.textoEfectividad = Null
Me.textoFrecuencia = Null
Me.textoResponsable = Null
If Trim(Me.textoControles.Value & vbNullString) = vbNullString Then
Me.textoEfectividad = Null
Me.textoFrecuencia = Null
Me.textoResponsable = Null
Exit Sub
End If
If Not IsError(Application.Match(Me.textoControles.Value, ws.ListObjects(ActiveSheet.Name).ListColumns(2).DataBodyRange, 0)) Then
Set C = ws.ListObjects(ActiveSheet.Name).ListColumns(2).DataBodyRange.Find(textoControles.Value, LookIn:=xlValues, lookat:=xlWhole)
index = C.Row
Set C2 = ws.ListObjects(ActiveSheet.Name).ListColumns(11).DataBodyRange.Find(ws.Cells(index, 11), LookIn:=xlFormulas, lookat:=xlWhole, SearchDirection:=xlPrevious) 'xlFormulas para buscar en celdas ocultas
index2 = C2.Row
For i = index To index2
If ws.Cells(i, 2) = Me.textoControles Then
Me.textoEfectividad = ws.Cells(i, 3)
Me.textoFrecuencia = ws.Cells(i, 4)
Me.textoResponsable = ws.Cells(i, 5)
Exit For
End If
Next i
End If
End Sub
It's the IsError function. In VBA it tells if a variant has the value vbError. I wanted to say this yesterday but I couldn't replicate the error. It doesn't seem to result from the Match function. Perhaps, the ListObject doesn't exist on a blank sheet causing an error to occur which doesn't assign a value of vbError to the variant resulting from the test. So, the thing to do is to assign Application.Match(Me.textoControles.Value, ws.ListObjects(ActiveSheet.Name).ListColumns(2).DataBodyRange to a temporary variable. Precede the line with On Error Resume Next and follow it with If Err Then, and your problem should go away.
My VBA script is supposed to split content in one cell by line breaks into several rows, it works for some cells, date in one cell look like this:
a01gestmstrs2a 10.67.15.17
a01gestmdb2a 10.67.15.19
a01gstdbldnim1a
a01rstdbldnim1a
a01gestmstrs2b (10.67.15.46)
a01restmdb2a (10.67.15.48)
a01gestmstrs2z 10.67.15.20
a01gestmdb2b (10.67.15.47)
a01restmstrs2a (10.67.15.49)
However, it fails to split for some such as the sample provided above, I can't figure out why.
My code:
Sub SplitMultipleHostnames()
Dim tmpArr As Variant
Dim s As String
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
For Each cell In Range("D2", Range("D3").End(xlDown))
For Each c In ActiveSheet.UsedRange
s = c.Value
If Trim(Application.Clean(s)) <> s Then
s = Trim(Application.Clean(s))
c.Value = s
End If
If cell.Value <> "" Then
If InStr(1, cell, Chr(10)) <> 0 Then
tmpArr = Split(cell, Chr(10))
cell.EntireRow.Copy
cell.Offset(1, 0).Resize(UBound(tmpArr), 1).EntireRow.Insert xlShiftDown
cell.Resize(UBound(tmpArr) + 1, 1) = Application.Transpose(tmpArr)
End If
Else
cell.EntireRow.Delete
cell.Row = cell.Row - 1
End If
Next
Next
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.CutCopyMode = False
End Sub
The loop that uses Trim() and Clean() will remove all ASCII 10's and 13's from the worksheet.
There will be nothing to Split().
They are not actually Char(10) they are spaces. I changed the code to " " and it worked fine
If cell.Value <> "" Then
If InStr(1, cell, " ") <> 0 Then
tmpArr = Split(cell, " ")