Dim rng2 As Range:
Set rng2 = ActiveSheet.Range("D:E", ActiveSheet.Cells.End(xlUp))
With rng2
.HorizontalAlignment = xlLeft
.Borders.LineStyle = xlContinous
End With
I understand my code like this.
rng2 is assigned to the Range "D:E" on the ActiveSheet. All Cells count to rng2 as long no blank cell occurs (End(xlUp))
With rng2 i assign to my Range rng2 the above mentioned settings which are left arrangement which works and Borders which shall in a continously Syle frame my rng2 - this does not work
I have to say that the first cell of D:E includes a value in D1 (header) but not in E1 (no header) is this the problem?
EDIT 17.05.21 full code
Sub Duplicate()
Dim nA As Long, nD As Long, i As Long, rc As Long
Dim s As String, j As Long
Range("A:A").Copy Range("D1")
Range("B1").Copy Range("E1")
Range("D:D").RemoveDuplicates Columns:=1, Header:=xlYes
rc = Rows.Count
nA = Cells(rc, 2).End(xlUp).Row
nD = Cells(rc, 4).End(xlUp).Row
For i = 2 To nD
v = Cells(i, 4)
V2 = ""
For j = 2 To nA
If v = Cells(j, 1) Then
V2 = V2 & Cells(j, 2) & ","
End If
Next j
Cells(i, 5) = Mid(V2, 1)
Next i
'neu
Dim rng2 As Range
Dim lastrow As Long
lastrow = ActiveSheet.UsedRange.Rows.Count
Set rng2 = ActiveSheet.Range("D1", "E" & lastrow)
With rng2
.HorizontalAlignment = xlLeft
.Borders.LineStyle = xlContinuous
End With
Debug.Print
End Sub
A better approach should be like this:
Dim rng2 As Range
dim lastrow as long
lastrow = ActiveSheet.UsedRange.Rows.Count
Set rng2 = ActiveSheet.Range("D1", "E" & lastrow)
With rng2
.HorizontalAlignment = xlLeft
.Borders.LineStyle = xlContinuous
End With
In additional, there is a typo on your code,
xlContinous should be xlContinuous
Continue to sort your row for the border issue. Assuming you have 2 col with difference row value. Col F has 8 rows, while Col H has 5 rows:
In order to obtain lastrow for different row, you can use the code as following:
Sub t()
Dim lastrowCola As Long
Dim lastrowColb As Long
lastrowCola = Sheet1.Range("F1").End(xlDown).Row
Debug.Print lastrowCola
lastrowColb = Sheet1.Range("H1").End(xlDown).Row
Debug.Print lastrowColb
End Sub
So debug.print for lastrowCola is 8, while lastrowColb is 5. Based on your scenario, you can adjust accordingly.
Related
i tried on more ways to border the result of the variable V2 in Column E but it doenst work. You can see my tryings as a comment within the code. Has anyone an idea? Thanks
By the way is it possible to figure out End(xlUp) & End(xlDown) just by a Macro?
Update
This i could figure out by pressing shift +Cntrl + ArrowDown
Sub Duplicate()
Dim nA As Long, nD As Long, i As Long, rc As Long
Dim s As String, j As Long
'Dim LastRow As Long
'Dim rng2 As Range
Range("A:A").Copy Range("D1")
Range("B1").Copy Range("E1")
Range("D:D").RemoveDuplicates Columns:=1, Header:=xlYes
rc = Rows.Count
nA = Cells(rc, 2).End(xlUp).Row 'grün
nD = Cells(rc, 4).End(xlUp).Row 'gelb
For i = 2 To nD 'gelb
v = Cells(i, 4) 'gelb
V2 = "" 'rot
For j = 2 To nA 'grün
If v = Cells(j, 1) Then 'orange
V2 = V2 & "," & Cells(j, 2) 'rot / ZU UMRANDEN
End If
Next j
Cells(i, 5) = Mid(V2, 1) 'rot / 1 = Start erstes Zeichen
Next i
'LastRow = Cells(Rows.Count, 5).End(xlUp).Row
'Range("E:E" & LastRow).Borders (xlInsideHorizontal)
'Set rng2 = ActiveSheet.Range("E:E", ActiveSheet.Cells(ActiveSheet.Rows.Count, 1).End(xlUp))
' rng2.HorizontalAlignment = xlLeft
'With rng2.Borders()
' .LineStyle = xlContinuous
' .ColorIndex = 0
' .TintAndShade = 0
' .Weight = xlThin
'End With
Debug.Print
End Sub
Update
How it is right now
How it shall be
Update
final need had been like this
From what I have understood, you are using remove duplicates on Col A values pasted in Column D (Code not there in question I guess) and then match the values with Col A to collate the values from Col B to create a summary kind of thing.
If my understanding is correct then there is a simpler way to do it.
LOGIC
Identify your range and store the values in an array. This is to speed things up. To identify the range, you can find the last row as shown HERE and then use that range.
Create a unique collection of values from Col A.
Define a second array based on unique values.
Compare the unique values with values in Col A and collate the values from Col B.
Clear Column D and E for output and finally output the array there.
Identify the final range to work with. You can then add color, border etc to that range.
CODE
I have commented the code but if you still have problems understanding it then do let me know.
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long, i As Long, j As Long
Dim MyAr As Variant, OutputAr As Variant
Dim col As New Collection
Dim itm As Variant
Dim tmpString As String
Dim rng As Range
'~~> Change this to the relevant sheet
Set ws = Sheet1
With ws
'~~> Find the last row in column A
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Store the Col A and B values in an array
MyAr = .Range("A1:B" & lRow).Value2
'~~> Loop through the array and get unique values from Col A
For i = LBound(MyAr) To UBound(MyAr)
On Error Resume Next
col.Add MyAr(i, 1), CStr(MyAr(i, 1))
On Error GoTo 0
Next i
End With
'~~> Define your output array based on unique values found
ReDim OutputAr(1 To col.Count, 1 To 2)
j = 1
'~~> Compare the unique values with values in Col `A`
'~~> and collate the values from Col `B`
For Each itm In col
OutputAr(j, 1) = itm
tmpString = ""
For i = LBound(MyAr) To UBound(MyAr)
If MyAr(i, 1) = itm Then
tmpString = tmpString & "," & MyAr(i, 2)
End If
Next i
OutputAr(j, 2) = "'" & Mid(tmpString, 2)
j = j + 1
Next itm
With ws
'~~> Clear Col D and E for output
.Columns("D:E").Clear
'~~> Output the array
.Range("D1").Resize(col.Count, 2).Value = OutputAr
'~~> This is the final range
Set rng = .Range("D1:E" & col.Count)
With rng
MsgBox .Address
'
'~~> Do what you want with the range here
'
End With
End With
End Sub
IN ACTION
An example to add borders
With rng
.Borders(xlDiagonalDown).LineStyle = xlNone
.Borders(xlDiagonalUp).LineStyle = xlNone
For i = 7 To 12
With .Borders(i)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
Next i
End With
Output
Similarly to center align the text
With rng
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlBottom
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
Output
I am trying to change the cells under B column to blue if the sum for the corresponding row is less than 55000. Below is my code I have figured out to achieve that for one row. How could I modify it so that it works for the other rows if I have a lot of rows?
Dim rng As Range
Dim result As Long
Set rng = Sheets(2).Range("C2:N2")
result = Application.WorksheetFunction.Sum(rng)
If result < 550000 Then
Sheet2.Range("B2").Font.Color = vbBlue
Sheet2.Range("B2").Font.Bold = True
End If
With a loop:
With Sheet2
Dim lastRow As Long
lastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
Dim i As Long
For i = 2 To lastRow
If Application.Sum(.Range("C" & i & ":N" & i)) < 550000 Then
.Cells(i, "B").Font.Color = vbBlue
.Cells(i, "B").Font.Bold = True
End If
Next
End With
EDIT:
If you want to do the same thing, but for columns instead of rows:
With Sheet2
Dim lastColumn As Long
lastColumn = .Cells(1, .Columns.Count).End(xlToRight).Column
For i = 3 To lastColumn
If Application.Sum(.Columns(i)) < 550000 Then
.Cells(1, i).Font.Color = vbBlue
.Cells(1, i).Font.Bold = True
End If
Next
End With
I'm trying to delete the last comma from each cell of a dynamic range.
The macro doesn't delete the comma, it just selects the range.
Sub selecting()
Dim sht As Worksheet
Dim LastColumn As Long
Dim StartCell As Range
Set sht = Worksheets("Sheet1")
Set StartCell = Range("D1")
'Find Last Row and Column
LastRow = sht.Cells(sht.Rows.Count, StartCell.Column).End(xlUp).row
LastColumn = sht.Cells(StartCell.row, sht.Columns.Count).End(xlToLeft).Column
'Select Range
sht.Range(StartCell, sht.Cells(LastRow, LastColumn)).Select
With ActiveCell
If Right(.Value, 1) = "," Then .Value = Right(.Value, Len(.Value) - 1)
End With
End Sub
Here is what is returned
Since you want to remove the last character from each cell in column D, try this variation on braX's comment. It loops trough each used cell in column 4 and deletes the last character.
With ThisWorkbook.Sheets("Sheet1")
For Each cel In .Range("D1", .Cells(.Rows.Count, 4).End(xlUp))
cel.Value = Left(cel, Len(cel) - 1)
Next cel
End With
The most conventional way would be to loop over your cells:
Sub Replacing()
Dim lr As Long, lc As Long
Dim rng As Range, cl As Range
With Worksheets("Sheet1")
'Find Last Row and Column
lr = .Cells(.Rows.Count, 1).End(xlUp).Row
lc = .Cells(1, .Columns.Count).End(xlToLeft).Column
'Go through range
Set rng = .Range(.Cells(1, lc), .Cells(lr, lc))
For Each cl In rng
If Right(cl.Value, 1) = "," Then cl.Value = Left(cl.Value, Len(cl.Value) - 1)
Next cl
End With
End Sub
Better would be to go through memory if your range is actually much larger (for performance sake)
Sub Replacing()
Dim lr As Long, lc As Long, x As Long
Dim arr As Variant
With Worksheets("Sheet1")
'Find Last Row and Column
lr = .Cells(.Rows.Count, 1).End(xlUp).Row
lc = .Cells(1, .Columns.Count).End(xlToLeft).Column
'Go through array
arr = .Range(.Cells(1, lc), .Cells(lr, lc)).Value
For x = LBound(arr) To UBound(arr)
If Right(arr(x, 1), 1) = "," Then arr(x, 1) = Left(arr(x, 1), Len(arr(x, 1)) - 1)
Next x
'Write array back to range
.Range(.Cells(1, lc), .Cells(lr, lc)).Value = arr
End With
End Sub
And a more less conventional way (alright for small ranges I guess) would be to evalate a range and avoid an iteration. This however comes at the cost of an array formula:
Sub Replacing()
Dim lr As Long, lc As Long
Dim rng As Range
With Worksheets("Sheet1")
'Find Last Row and Column
lr = .Cells(.Rows.Count, 1).End(xlUp).Row
lc = .Cells(1, .Columns.Count).End(xlToLeft).Column
'Evaluate your range
Set rng = .Range(.Cells(1, lc), .Cells(lr, lc))
rng.Value = .Evaluate("IF(RIGHT(" & rng.Address & ",1)="","",LEFT(" & rng.Address & ",LEN(" & rng.Address & ")-1)," & rng.Address & ")")
End With
End Sub
Use the Replace() function:
For Each Cell in Range.Cells
Cell.Value = Replace(Cell.Text, ",", "")
Next Cell
Edit: After testing, replaced .Text with .Value
Edit 2: I'd also like to add, why are you selecting the range? My supposition is that you are selecting it to enable use of ActiveCell but you can simply manipulate the range without selecting it. Selecting the range is asking to incur errors. My suggestion is:
Dim rplcRng as Range
Set rplcRange = sht.Range(StartCell, sht.Cells(LastRow, LastColumn))
For Each Cell in rplcRng.Cells
Cell.Value = Replace(Cell.Text, ",", "")
Next Cell
Edit 3: added "s"s
I have been trying to come up with/find a VBA code that copies blocks of data under my first block. Each block is 19 columns followed by a blank. The number of rows per block can vary.
See my screenshot below:
Therefore, I would like all my data continuous in the first columns A:S. Any help is highly appreciated.
I found the following code online, but this only pastes everything into the first column
Sub Column()
Dim iLastcol As Long
Dim iLastRow As Long
Dim jLastrow As Long
Dim ColNdx As Long
Dim ws As Worksheet
Dim myRng As Range
Dim ExcludeBlanks As Boolean
Dim mycell As Range
ExcludeBlanks = (MsgBox("Exclude Blanks", vbYesNo) = vbYes)
Set ws = ActiveSheet
iLastcol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
On Error Resume Next
Application.DisplayAlerts = False
Worksheets("Alldata").Delete
Application.DisplayAlerts = True
Sheets.Add.Name = "Alldata"
For ColNdx = 1 To iLastcol
iLastRow = ws.Cells(ws.Rows.Count, ColNdx).End(xlUp).Row
Set myRng = ws.Range(ws.Cells(1, ColNdx), _
ws.Cells(iLastRow, ColNdx))
If ExcludeBlanks Then
For Each mycell In myRng
If mycell.Value <> "" Then
jLastrow = Sheets("Alldata").Cells(Rows.Count, 1) _
.End(xlUp).Row
mycell.Copy
Sheets("Alldata").Cells(jLastrow + 1, 1) _
.PasteSpecial xlPasteValues
End If
Next mycell
Else
myRng.Copy
jLastrow = Sheets("Alldata").Cells(Rows.Count, 1) _
.End(xlUp).Row
mycell.Copy
Sheets("Alldata").Cells(jLastrow + 1, 1) _
.PasteSpecial xlPasteValues
End If
Next
Sheets("Alldata").Rows("1:1").EntireRow.Delete
ws.Activate
End Sub
Basic approach:
Sub Tester()
Dim c As Range, addr
Set c = ActiveSheet.Range("T1")
Do
Set c = c.End(xlToRight)
If c.Column = Columns.Count Then Exit Do
addr = c.Address 'strire the address since Cut will move c
c.CurrentRegion.Cut c.Parent.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
Set c = ActiveSheet.Range(addr) '<< reset c
Loop
End Sub
This is a little more basic than #TimWilliams
With ThisWorkbook.Sheets("Alldata")
Dim lRow As Long, lCol As Long, cpyrng As Range
lCol = Cells(1, Columns.Count).End(xlToLeft).Column
For i = 21 To lCol Step 20
If .Cells(1, i).Value <> "" And .Cells(1, i).Offset(, -1).Value = "" Then
lRow = .Cells(.Rows.Count, 1).End(xlUp).Row
Set cpyrng = .Cells(1, i).CurrentRegion
cpyrng.Cut
Sheets("Sheet2").Cells(lRow, 1).Offset(2).Insert Shift:=xlDown
End If
Next i
End With
I want to check for dupes in Row One
The Code below works fine for column ranges like:
myrng = Range("C2:C" & Range("C65536").End(xlUp).Row)
and
If WorksheetFunction.CountIf(Range("C2:C" & cel.Row), cel) = 1 Then
But if I change to Row 1 the code only highlights one cell of the duplicates
Thanks
First Row
Sub HilightDupsRow1()
Dim ws As Worksheet
Dim cel As Variant
Dim myrng As Range
Dim clr As Long, LC As Long, cnt1 As Long, cnt2 As Long
Set ws = ThisWorkbook.Sheets("Nodes")
With ws
LC = .Cells(1, .Columns.Count).End(xlToLeft).Column
Set myrng = .Range(.Cells(1, 1), .Cells(1, LC))
myrng.Interior.ColorIndex = xlNone
clr = 3
For Each cel In myrng
If Application.WorksheetFunction.CountIf(myrng, cel) > 1 Then
If WorksheetFunction.CountIf(.Range(.Cells(1, 1), .Cells(1, cel.Column)) cel) > 1 Then
cel.Interior.ColorIndex = clr
clr = clr + 1
Else
cel.Interior.ColorIndex = myrng.Cells(WorksheetFunction.Match(cel.Value, myrng, False), 1).Interior.ColorIndex
End If
End If
Next cel
End With
End Sub
Use Collections to get the unique values, then loop through the collections to highlight the duplicates.
Sub UsingCollection()
Dim cUnique As Collection
Dim Rng As Range
Dim Cell As Range
Dim sh As Worksheet
Dim vNum As Variant
Dim LstCol As Long
Dim c As Long, clr As Long, x, r As Range
Set sh = ThisWorkbook.Sheets("Nodes")
With sh
LstCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
Set Rng = .Range(.Cells(1, 1), .Cells(1, LstCol))
Set cUnique = New Collection
Rng.Interior.ColorIndex = xlNone
clr = 3
On Error Resume Next
For Each Cell In Rng.Cells
cUnique.Add Cell.Value, CStr(Cell.Value)
Next Cell
On Error GoTo 0
For Each vNum In cUnique
For c = 1 To LstCol
Set r = .Cells(1, c)
x = Application.WorksheetFunction.CountIf(.Range(.Cells(1, 1), .Cells(1, c)), r)
If r = vNum Then
If x > 1 Then
r.Interior.ColorIndex = clr
End If
End If
Next c
clr = clr + 1
Next vNum
End With
End Sub