I got a code here while researching on how to add cells based on a criteria to a defined range. This was the code:
Dim rng1 As Range
Dim rng2 As Range
Dim c As Range
Set rng1 = Range("N1:N10")
For Each c In rng1
' Add cells to rng2 if it is highlighted with a certain color
If c.Interior.ColorIndex = 43
If Not rng2 Is Nothing Then
Set rng2 = Union(rng2, c)
Else
' the first valid cell becomes rng2
Set rng2 = c
End If
End If
Next
What I plan on doing with the retrieved cell was to get the value and add them. My initial plan was to use the formula SUM() where the range of the sum is the
supposed rng2. In order for me to put it in this formula, I'd have to extract the cells from the retrieved range. So upon research, I stumbled upon this code:
Function RangeToString(ByVal myRange As Range) As String
RangeToString = ""
If Not myRange Is Nothing Then
Dim myCell As Range
For Each myCell In myRange
RangeToString = RangeToString & ";" & myCell.Value
Next myCell
'Remove extra comma
RangeToString = Right(RangeToString, Len(RangeToString) - 1)
End If
End Function
With the following functions and codes, I did a test run just to check if it picked up any of the highlighted cells. Sadly, It didn't post any value on the test cell I coded. Here's the sample code I did:
Dim totalsum As String
totalsum = RangeToString(rng2)
ThisWorkbook.Sheets("format").Range("N" & counter).Value = totalsum
Thanks in advance! Sorry for the lengthy question.
If all you're needing is the sum of rng2, you can just use use Worksheetfunction.Sum() and use rng2 as the argument.
Debug.print WorksheetFunction.Sum(rng2)
No need to parse out the individual values of each cell in the range to use in the worksheet.
Related
I want to copy all filled cells starting from C5 to column F of a different worksheet.
I referred to another post: Excel - Combine multiple columns into one column
Modified the code based on my needs.
Sub CombineColumns()
Dim Range1 As Range, iCol As Long, Range2 As Range, Check As Range, wks As Worksheets
Set Range1 = wks("T(M)").Range(Cells(5, 3), Cells(Cells(5, 3).End(xlDown).Row, Cells(5, 3).End(xlToRight).Column))
Set Check = wks("csv").Range("F1")
If IsEmpty(Check.Value) = True Then
Set Range2 = Check
Else
LastRow = wks("csv").Range("F" & Rows.Count).End(xlUp).Row
Set Range2 = wks("csv").Cells(LastRow, 6).Offset(1, 0)
End If
For iCol = 3 To Range1.Columns.Count
wks("T(M)").Range(Cells(5, iCol), Cells(Range1.Columns(iCol).Rows.Count, iCol)).Copy
wks("csv").Range2.PasteSpecial Paste:=xlPasteValuesAndNumberFormats
Next iCol
End Sub
But I kept getting the error message
"object doesn't support this method or property"
at the step of pasting. After I tried to qualify all the ranges, It says I didn't set the object variable.
Thank you so much for the help!
How about this?
Sub Transposes()
' Example just for hardcoded data
Dim inputRange As Range
Set inputRange = Sheets("Sheet1").Range("C5:F10").SpecialCells(xlCellTypeConstants)
Dim outputCell As Range
Set outputCell = Sheets("Sheet2").Range("A1")
Dim cell As Range
For Each cell In inputRange
Dim offset As Long
outputCell.offset(offset).Value = cell.Value
offset = offset + 1
Next cell
End Sub
Set the last row in ColumnF to be whatever you want, and if that changes dynamically, just use any one of the multiple techniques out there to find the last cell you need to copy/paste.
I have a set of formats in a column (n rows long) that I want to apply to a table (13 cols x n rows). The formats stored in the column are dynamic and based upon the type of data eg currency, %, etc. For example: #,##0;[Red](#,##0);"-" or 0.0%;[Red]0.0%;"-"
I want each row of the table to be formatted any time the column is updated.
Note: I am not interested in conditional formatting.
I originally tried referring directly to rng2 as in row.NumberFormat = rng2 but that seemed to get stuck in a never-ending loop.
Sub formatrows()
Dim rng1 As Range
Dim rng2 As Range
Dim row As Range
Dim i As Integer
Set rng1 = Range("Ac7:ao400")
Set rng2 = Range("d7:d400")
i = 0
Range("AC7").Select
'rng1.ClearFormats
For Each row In rng1.Rows
row.NumberFormat = ActiveCell.Offset(i, -25)
i = i + 1
Next row
End Sub
Here's what I came up with seems to work but rather clunky and I'm sure there's a better way to do this?
Simplifying a bit:
Sub formatrows()
Dim rng1 As Range
Dim row As Range
Set rng1 = Range("Ac7:ao400")
'rng1.ClearFormats
For Each row In rng1.Rows
row.NumberFormat = row.EntireRow.Cells(4).value 'take format from ColD
Next row
End Sub
I am trying to add up the numbers that are in a column, but the column of numbers varies so I'm using the Rows.Count instead of a set number of rows such as "a1:a5". Each time I run this I get the row count (represented as rngcount) but instead of the sum of the cells within the row count (rngcount) I get the row count again.
I was getting an object error (1004) until I added "a" to .Range("a" & rngcount) but I admit I'm not sure why the "a" is needed as I thought the rngcountwould be all that is needed to Sum.
So Unfortunately two issues in one post.
Sub simpleSUM()
Dim rng1 As Range
Dim rng2 As Range
Dim rngcount As Integer
Set rng1 = Range("b1") 'This indicates how many cells are in use
Set rng2 = Range("b2") 'This indicates the sum of the cells that are in use
rngcount = cells(Rows.Count, "A").End(xlUp).row
rng1.Value = rngcount
rng2.Value = Application.WorksheetFunction.Sum(ThisWorkbook.Sheets("sheet2").Range("a" & rngcount))
End Sub
Your code now only counts the last row. The variable rngcount returns the last rownumber in the range, instead of the whole range.
It should work if you use
rng2.Value = Application.WorksheetFunction.Sum(Thisworkbook.Sheets("sheet2").Range("A1:A" & rngcount))
I want to copy and paste values to a range of cells but only if their value = "N/A". I want to leave the formulas as they are in all the cells that do not = "N/A".
In context, I have hundreds of VLOOKUPs. Example:
=IFERROR(VLOOKUP("L0"&MID(G$4,1,1)&"A0"&MID(G$4,1,1)&MID(G$4,3,2)&"-0"&$B6,Sheet1!$C:$D,2,FALSE),"N/A")
Is this possible with VBA?
First of all, you should use real error values rather than string that only look like errors. Secondly, VLOOKUP returns the N/A error directly if the lookup value is not found, so the IFERROR wrapper can be dispenced with. So the formula
=VLOOKUP("L0"&MID(G$4,1,1)&"A0"&MID(G$4,1,1)&MID(G$4,3,2)&"-0"&$B6,Sheet1!$C:$D,2,FALSE)
is sufficient as is.
To replace N/A results with error values, you can use this
Sub Demo()
Dim ws As Worksheet
Dim rngSrc As Range
Dim datV As Variant, datF As Variant
Dim i As Long
' Get range to process by any means you choose
' For example
Set ws = ActiveSheet
With ws
Set rngSrc = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp))
End With
' Copy data to variant arrays for efficiency
datV = rngSrc.Value
datF = rngSrc.Formula
' replace erroring formulas
For i = 1 To UBound(datV, 1)
If IsError(datV(i, 1)) Then
If datV(i, 1) = CVErr(xlErrNA) Then
datF(i, 1) = CVErr(xlErrNA)
End If
End If
Next
' return data from variant arrays to sheet
rngSrc.Formula = datF
End Sub
If you really want to use strings rather than true error values, adapt the If lines to suit
Rather than loop through all cells in a range, you can use SpecialCells to shorten working with the =NA()cells
This also open up a non-VBA method (if the only error cells are NA, ie no Div#/0)
The first two methods below (manual and code) deal with the situation where you only gave NA cells
the third uses SpecialCells to focus on only the cells that need to be tested, before then running a check for NA before making updates
option1
Manual selection of formula cells that evaluate to errors
Select the range of interest
Press [F5].
Click Special
Select Formulas
check only Errors
option2
VBA updating formula cells that evaluate to errors
code
Sub Shorter()
Dim rng1 As Range
On Error Resume Next
' All error formulas in column A
Set rng1 = Columns("A").SpecialCells(xlCellTypeFormulas, 16)
On Error GoTo 0
If rng1 Is Nothing Then Exit Sub
'update with new value (could be value or formulae)
rng1.Value = "new value"
End Sub
option 3
Test for =NA()
Sub TestSpecificRegion()
Dim rng1 As Range
Dim rng2 As Range
Dim X
Dim lngRow As Long
On Error Resume Next
' All error formulas in column A
Set rng1 = Columns("A").SpecialCells(xlCellTypeFormulas, 16)
On Error GoTo 0
If rng1 Is Nothing Then Exit Sub
'update with new value (could be value or formulae)
For Each rng2 In rng1.Areas
If rng2.Cells.Count > 1 Then
X = rng2.Value2
For lngRow = 1 To UBound(X, 1)
If X(lngRow, 1) = CVErr(xlErrNA) Then X(lngRow, 1) = "new value"
Next
rng2.Value = X
Else
If rng2.Value2 = CVErr(xlErrNA) Then rng2.Value = "new value"
End If
Next
End Sub
In my Excel sheet, I have VBA code to detect the last non-empty cell in Column A and add incremental serial number value in that cell (in below example cell A6 value should be SN104).
This processing is limited only to Column A, and in this image example first non-empty last cell is at A6, sometimes it can be after 100 cells or 1000 cells.
Is there any simple way to handle this scenario?
Public Function GetLastCell(ByVal startRng as Range) as Range
With startRng
Set GetLastCell = IIf(.Offset(1).Value = "", .Offset(0), .End(xlDown))
End With
End Function
For your example, you can define a Range variable rng, and call the above function in this way:
Dim rng as Range
Set rng = GetLastCell( Range("A1") )
Then rng is referring to the last cell of Column A
Something like
Dim lngLastUsedRow as Integer
lngLastUsedRow = Range("A65536").End(xlUp).Row
Dim lngFirstEmptyRow as Integer
lngFirstEmptyRow = Range("A65536").End(xlUp).Offset(1,0)
// do your increment
newValue = Cint(Mid(CurrentWorkSheet.Range("A" + lngLastUsedRow).Value,2)) + 1
CurrentWorkSheet.Range("A" & lngFirstEmptyRow).Value = "SN" + newValue
I don't have excel on me, I can't test it right now. But this should get you started.
Something like this which
Find the true last used cell in any Excel version, and handles a blank result
Parses the string in the last non-blank cell (handling any length of alpha then numeric)to update the next blank cell
Sub GetTrueLastCell()
Dim rng1 As Range
Dim objRegex As Object
Dim strFirst As String
Set rng1 = Columns("A").Find("*", [a1], xlFormulas)
If Not rng1 Is Nothing Then
Set objRegex = CreateObject("vbscript.regexp")
With objRegex
.Pattern = "^(.+?[^\d])(\d+)$"
If .test(rng1.Value) Then
strFirst = .Replace(rng1.Value, "$1")
rng1.Value = strFirst & (Val(Right$(rng1.Value, Len(rng1.Value) - Len(strFirst)) + 1))
End If
End With
Else
MsgBox "Data range is blank"
End If
End Sub
Assumptions:
Next cell in list is empty
Serial N's only have three digits after 'SN' string (i.e., if it reaches 1000, earlier ones don't need padding, like '0100'
-
Dim rAll As Range, rLast As Range, rNext As Range, iNextSN As Integer
Set rAll = Intersect(Sheet1.Cells(1).CurrentRegion, Sheet1.Columns(1)) ' Column 'A' can be contiguous with others
Set rLast = rAll.Cells(rAll.Cells.Count) ' Last cell in current list
Set rNext = rLast.Offset(1) ' Next cell below current list
iNextSN = CInt(Right(rLast.Value, 3)) ' Get value of last serial N
rNext.Value = "SN" & iNextSN + 1 ' Assemble next SN with increment
-