Excel VBA: Maintaining number formatting with digits and letters - excel

I am writing a code where basically I need to follow the sequence in logic. I am going through all the lines
Set rep = Sheets("Details")
For i = 2 To n
If Sheets("Work").Range("A:A").Find(Worksheets("Work_report").Range("E" & i).Value, lookat:=xlWhole) Is Nothing Then
Else:
o = rep.Range("A" & Rows.Count).End(xlUp).Row + 1
rep.Range("A" & o).Value = "FT_EXCEL"
rep.Range("B" & o).Value = Sheets("Start").Range("C5") & "AB" & o - 1
End If
Next i
So this the last line (there are more than 50 in original code) returns me a value of the cell C5 (20170331) & AB & the o minus 1 (because I have started at 2 (1st line header)). So this is giving 20170331AB1, but it should give 20170331AB01 (zero before the 0). This sequence works like a charm after 10, but before ten when I need to add a zero - I got stuck.
Any ideas? Thank you.

Try this:
rep.Range("B" & o).Value = Sheets("Start").Range("C5") & "AB" & Format(o - 1, "00")

you can do it in one shot with exploiting AutoFilter() method's operator xlFilterValues value
Sub main()
Dim rep As Worksheet
Dim criteriaArr As Variant
With Worksheets("Work_report") '<--| reference "Work_report" sheet
criteriaArr = Application.Transpose(.Range("E2", .Cells(.Rows.Count, "E").End(xlUp)).Value) '<--| store its column E cells content from row 2 down to last not empty one
End With
Set rep = Sheets("Details")
With Worksheets("Work") '<--| reference "Work" sheet
With .Range("A1", .Cells(.Rows.Count, "A").End(xlUp)) '<--| reference its column A cells from row 1 (header) down to last not empty one
.AutoFilter Field:=1, Criteria1:=criteriaArr, Operator:=xlFilterValues '<--| filter it with "Work_report" sheet column E content
If Application.WorksheetFunction.Subtotal(103, .Cells) > 1 Then '<--| if any filtered cells other then headers
With .Offset(1).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible) '<--| reference filtered cells skipping header
rep.Range("A" & Rows.Count).End(xlUp).Offset(1).Resize(.Rows.Count).Value = "FT_EXCEL" '<--| write 'rep' sheet column A corresponding cells content
With rep.Range("B" & Rows.Count).End(xlUp).Offset(1).Resize(.Rows.Count)
.Formula = "=CONCATENATE(Start!$C$5,""AB"",TEXT(ROW(),""00""))" '<--| '<--| write 'rep' sheet column B corresponding cells content
.Value = .Value
End With
End With
End If
End With
.AutoFilterMode = False
End With
End Sub

Related

vba, sum based on column header

I need your help with VBA!
I want to write a code that will sum the "sales" column in different 7 sheets. The problem is that the column has a different location in each sheet and a dinamic rows' count. The sum should be in the last row + 1.
I am not very good at macros, but I guess I should start with checking i to 7 sheets. Then I should sum a range based on the header ("Sales"). I am lost about how to write all of this..
Try the next code, please:
Sub SumSales()
Dim sh As Worksheet, rngS As Range, lastRow As Long
For Each sh In ActiveWorkbook.Sheets 'iterate through all sheets
'find the cell having "Sales" text/value
Set rngS = sh.Range(sh.Cells(1, 1), sh.Cells(1, _
sh.Cells(1, Columns.count).End(xlToLeft).Column)).Find("Sales")
'if the cell has been found (the cell range is NOT Nothing...)
If Not rngS Is Nothing Then
'Determine the last row of the found cell column:
lastRow = sh.Cells(Rows.count, rngS.Column).End(xlUp).row
'Write the Sum formula in the last empty cell:
rngS.Offset(lastRow).formula = "=Sum(" & rngS.Offset(1).address & _
":" & sh.Cells(lastRow, rngS.Column).address & ")"
sh.Range("A" & lastRow + 1).Value = "Sum of sales is:"
Else
'if any cell has been found, it returns in Immediate Window (Being in VBE, Ctrl + G) the sheet names not having "Sales" header:
Debug.Print "No ""Sales"" column in sheet """ & sh.name & """."
End If
Next
End Sub

Excel VBA is Finding Every Other Cell not Every Cell From Method

Excel VBA is finding every other cell using a method to check for Empty Cells. On the next time running the same macro, it then finds the cell that it skipped over on the last run while again skipping the next instance of an empty cell. If I cycle through the macro a few times, eventually every row without data is getting deleted, as per the purpose of the macro. The rows do shift upward upon deletion of the row one at a time, I will try a Union and delete the Range as stated by #BigBen
When a cell that is empty is found, it checks columns A, B, and D to see if formula is applied, and if a formula exists in that row, the entire row gets deleted.
Dim cel, dataCells As Range
Dim rngBlank, dc As Range
Dim lastRow, cForm, c, blnkRange As String
Dim cycleTimes As Integer
On Error Resume Next
Set dataCells = Range("F2:W2").Cells 'This is header of the table of data
cycleTimes = dataCells.Count 'Number of times to cycle through macro
For Count = 1 To cycleTimes 'I don't want to cycle through macro
lastRow = Range("N" & Rows.Count).End(xlUp).Row 'To find end of column
For Each dc In dataCells
c = Split(Cells(1, dc.Column).Address, "$")(1) 'Column Letter
blnkRange = c & "3:" & c & lastRow 'Range to look over for empty cells
Set rngBlank = Range(blnkRange).SpecialCells(xlCellTypeBlanks).Cells
For Each cel In rngBlank '**Skipping Every other Row**
If Not TypeName(cel) = "Empty" Then
cForm = "A" & cel.Row & ",B" & cel.Row & ",D" & cel.Row 'Formula check
If Range(cForm).HasFormula Then
cel.EntireRow.Delete
End If
End If
Next
Next
Next
I was able to use Intersect to find the rows that matched the criteria I was searching for and delete the EntireRow even though the Selection was in separate Rows.
Set dataCells = Range("F2:W2").Cells
lastRow = Range("N" & Rows.Count).End(xlUp).Row 'To find last row to generate range to look through
For Each dc In dataCells 'Have to perform delete row for every column
c = Split(Cells(1, dc.Column).Address, "$")(1)
blnkRange = c & "3:" & c & lastRow
Set rngBlank = Range(blnkRange).SpecialCells(xlCellTypeBlanks).EntireRow
strFormula = "A2:A" & lastRow & ",B2:B" & lastRow & ",C2:C" & lastRow
Set rngFormula = Range(strFormula).SpecialCells(xlCellTypeFormulas)
Intersect(rngFormula, rngBlank).EntireRow.Delete (xlShiftUp) '**THIS helped in deleting Rows**
Next

FormulaR1C1 sumIF delete duplcates + concatenate

I'm trying to get the below code to work for my sheet.
Sub main()
Dim helperRng As Range, dataRng As Range
Dim colToFilter As String
Dim colsToSumUp As Long
With Worksheets("Transactions") '<== change "Sheet01" as per your actual sheet name
Set dataRng = .Range("A3:K3").Resize(.Cells(.Rows.Count, 1).End(xlUp).Row - 1)
colToFilter = "A" ' set here the column header you want to sum up on
colsToSumUp = 5 ' number of adjacent columns to sum up with
Set helperRng = dataRng.Offset(, .UsedRange.Columns.Count + 1).Resize(, 1) 'localize "helper" cells
first column out of sheet used range
With helperRng
.FormulaR1C1 = "=RC" & Cells(1, colToFilter).Column 'make a copy of the values you want to sum up on
.Offset(, 1).FormulaR1C1 = "=if(countif(R1C[-1]:RC[-1], RC[-1])=1,1,"""")" 'localize with "1" first occurrence of each unique value
With .Offset(, 2).Resize(, colsToSumUp)
.FormulaR1C1 = "=sumif(C" & helperRng.Column & ", RC" & helperRng.Column & ",C[" & Cells(1, colToFilter).Column - helperRng.Column - 1 & "])" 'sum up in adjacent columns
.Value = .Value 'get rid of formulas
End With
.Offset(, 1).SpecialCells(xlCellTypeFormulas, xlTextValues).EntireRow.Delete 'delete rows with repeted values you want to sum up on
dataRng.Columns(2).Resize(.Rows.Count, colsToSumUp).Value = .Offset(, 2).Resize(.Rows.Count, colsToSumUp).Value 'copy summed up values from "helper" cells
helperRng.Resize(, 1 + 1 + colsToSumUp).Clear 'clear "helper" cells
End With
End With
End Sub
Basically i want ik to search for duplicates in column A and sum up the values in column E and concatenate tekst in columns F:J

VBA - Remove rows that have every cell in the range that contain black text

I've been tasked to analyse a workbook where I need to isolate the data based on the colour (red or black) that the text is in relating to the rows.
I essentially need to develop a macro that will remove all the rows that contain data (text) that is 'all black' in the range (column C-J) and leave all the rows that contain at least one cell in the range (column C-J) that contains text that is 'red' (255,0,0).
The completed result should be that every row will contain at least one cell that contains red text between between Column C-J.
The data is set our as follows:
Names:
A1,B1
A2,B2 all the way to
A2000,B2000
Data (text) is set up like the following:
C1 to J1
C2 to J2 all the way to
C2000, J2000
I've found numerous codes that conditionally colour format but I can't seem to develop one that does what I want above.
Any help will be greatly appreciated.
I may as well offer another opinion, just for fun. :-)
Copy and paste the below into a new module, select the area of cells you want to run this over and then execute the macro.
Public Sub RemoveAllRowsWithBlackText()
Dim rngCells As Range, bFoundNonBlack As Boolean, lngRow As Long
Dim lngCol As Long
Set rngCells = Selection
Application.ScreenUpdating = False
With rngCells
For lngRow = .Rows.Count To 1 Step -1
bFoundNonBlack = False
For lngCol = 1 To .Columns.Count
If .Cells(lngRow, lngCol).Font.Color <> 0 And Trim(.Cells(lngRow, lngCol)) <> "" Then
bFoundNonBlack = True
Exit For
End If
Next
If Not bFoundNonBlack Then
.Cells(lngRow, lngCol).EntireRow.Delete xlShiftUp
End If
Next
End With
Application.ScreenUpdating = True
End Sub
... it's not bound to your columns, it will move with the selection you make.
You could try:
Option Explicit
Sub test()
Dim i As Long
With ThisWorkbook.Worksheets("Sheet1")
For i = 2000 To 2 Step -1
If .Range("C" & i).Value = "" And .Range("D" & i).Value = "" And .Range("E" & i).Value = "" And .Range("F" & i).Value = "" _
And .Range("G" & i).Value = "" And .Range("H" & i).Value = "" And .Range("I" & i).Value = "" And .Range("J" & i).Value = "" Then
.Rows(i).Delete
End If
Next i
End With
End Sub
You can use AutoFilter to filter by font color. It does not matter whether the color was derived by manual formatting or conditional formatting.
In your case, you are 'proofing a negative' across many columns. A helper column appears necessary. The code below cycles through columns C:J and marks the 'helper' column every time it encounters filtered rows with a red font.
Sub anyRedFont()
Dim c As Long
With Worksheets("sheet1")
'remove any AutoFilters
If .AutoFilterMode Then .AutoFilterMode = False
'insert a 'helper' column and label it
.Columns("C").Insert
.Cells(1, "C") = "helper"
'filter for red font color
With .Range(Cells(1, "C"), .Cells(.Rows.Count, "K").End(xlUp))
'cycle through columns looking for red font
For c = 2 To 9
'fliter for red font
.AutoFilter Field:=c, Criteria1:=vbRed, _
Operator:=xlFilterFontColor, VisibleDropDown:=False
'put a value into the 'helper' column
On Error Resume Next
With .Resize(.Rows.Count - 1, 1).Offset(1, 0)
Debug.Print .SpecialCells(xlCellTypeVisible).Address(0, 0)
.SpecialCells(xlCellTypeVisible) = 1
End With
On Error GoTo 0
'remove fliter for red font
.AutoFilter Field:=c
Next c
'fliter for non-blank helper column
.AutoFilter Field:=1, Criteria1:=1, VisibleDropDown:=False
End With
'Do your work with the rows containing at least one cell
'with red font here
'remove 'helper' column
'this removes the AutoFilter since the 'helper' column
'is the primary filter column at this point
'.Columns(Application.Match("helper", .Rows(1), 0)).Delete
'remove AutoFilter (manually with Data, Data Tools, Clear)
'If .AutoFilterMode Then .AutoFilterMode = False
End With
End Sub
I've commented out removing the 'helper' column. The 'helper' is the primary filter column so removing it also removes the AutoFilter.

How to delete all rows of a multiple entry even if just one row meets defined criteria

Below is the current (incomplete) code I'm using which works fine to delete any one given row, but what I really need to do is identify rows which meet certain criteria:
Cell Value in Column L > 90%
OR
Cell Value in Column M > 90%
Then if either of those is true I need to find the Cell Value in same row Column G and delete all rows which contain that same Value in Column G.
Sub sbDelete_Rows_Based_On_Multiple_Criteria()
Dim lRow As Long
Dim iCntr As Long
lRow = Cells(Rows.Count, "G").End(xlUp).Row
For iCntr = lRow To 2 Step -1
If Cells(iCntr, "L") > 0.90 OR Cells(iCntr, "M") > 0.90 Then
Cells(iCntr, "G").EntireRow.Delete
End If
Next iCntr
End Sub
--
What I hope to accomplish in my example would result in the only Serial # which is NOT deleted would be 1910910
thank you in advance for your assistance.
Sub ToDelete()
Dim last_row&
'// NOTE! The code assumes that range:
'// 1) starts in column A
'// 2) ends in column O
last_row = Cells(Rows.Count, "G").End(xlUp).Row
'// Helper column 1
With Range("P2:P" & last_row)
.Formula = "=IF(OR(M2>0.9,L2>0.9),1,0)"
.Value = .Value 'Overwrite formula
End With
'// Helper column 2
With Range("Q2:Q" & last_row)
.Formula = "=IF(SUMIF(G:G,G2,P:P)>0,1,0)"
.Value = .Value 'Overwrite formula
End With
Rows(1).CurrentRegion.AutoFilter Field:=17, Criteria1:=1
Rows("2:" & last_row).EntireRow.Delete
ActiveSheet.AutoFilterMode = False 'Remove filter
Columns("P:Q").Delete 'Remove helper columns
End Sub

Resources