I want to be able to delete all of the spaces from a group of cells so that the cell contents result in just being a string of information that I want. I have come up with a code but it doesn't work and I can't figure out whether I have to use a replace function or not
My code is:
Sub Tester()
Dim SearchString As String
Dim cell As Range
Dim LastRowSource As Long
Dim ws1 As Worksheet
Set ws1 = ActiveWorkbook.ActiveSheet
SearchString = " " 'look for strings containing ( )
With ws1
LastRowSource = .Cells.Find(" ", [B2], , , xlByRows, xlPrevious).Row
For Each cell In .Range("B2:B" & LastRowSource)
If InStr(cell.Value, SearchString) > 0 Then
cell.Value = Replace(" ", "")
End If
Next cell
End Sub
If you need to do this programmatically then, recording a Macro using the Replace dialog generates this code:
Sub Macro1()
Selection.Replace What:=" ", Replacement:="", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
End Sub
Substitute your range for Selection. You do not need to iterate each cell.
You don't need to loop:
With ws1
.Range("B2", .Cells(.rows.count, "B").End(xlUp)).Replace " ", vbnullstring, xlpart
End With
Try like this:
LastRowSource = 10000.
If it works, then the problem is the way you are setting the last row. Thus, add the LastRow() function to your code, it should work:
LastRowSource = LastRow ws1
Function LastRow(sh As Worksheet)
On Error Resume Next
LastRow = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
End Function
Function from here - https://www.rondebruin.nl/win/s9/win005.htm
Related
I need to manipulate an Excel worksheet in code using MS Access and need to find the last used column in my opened Excel file. I would also need to find the last used row in a column.
Here are functions I am using:
Public Function FindLastColumnInWSheet(ws As Worksheet) As Long
Dim LastCol As Long
Dim rng As Range
Set rng = ws.Cells.Find(What:="*", _
After:=ws.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False)
If rng Is Nothing Then
LastCol = 1
Else
LastCol = rng.column
End If
FindLastColumnInWSheet = LastCol
End Function
Public Function FindLastRowInColumn(wsheet As Worksheet, columnName As String) As Integer
With wsheet
FindLastRowInColumn = .Range(columnName & .rows.Count).End(xlUp).row
End With
End Function
The Sub written below is designed to open a workbook and copy the sheets into a template, then close the workbook leaving the template open. It works, but there is data until row 19195 but only 12135 rows of data get copied. What is my problem in the Sub?
Sub CopySheetsl()
Dim wb As Workbook, wb1 As Workbook
Dim CopySht As Worksheet
Dim LastRow As Long
Set wb = Workbooks.Open("L:\ABC\test\macro\test.xlsx")
Set wb1 = Workbooks("macro.xlsm")
LastRow = range("A:A").Find("", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
wb1.Sheets("Sheet1").range("A1", "N1" & LastRow) = wb.Sheets("Sheet1").range("A1", "N1" & LastRow).Value
wb1.Sheets("Sheet2").range("C1", "AN1" & LastRow) = wb.Sheets("Sheet2").range("A1", "AL1" & LastRow).Value
wb.Close
End Sub
This isn't finding the last row, it's finding an empty cell.
Dim ws as Worksheet : Set ws = wb1.Sheets("Sheet1")
LastRow = ws.Cells(ws.rows.count, 1).End(xlUp).Row ' last populated row in column A
You'll also need to recalculate it for Sheet2 unless you can be absolutely sure that both sheets have the same number of rows.
From Ron De Bruin's site
Public Function fndLast(choice As Long, rng As Range)
'Ron de Bruin, 5 May 2008
' 1 = last row
' 2 = last column
' 3 = last cell
Dim lrw As Long
Dim lcol As Long
Select Case choice
Case 1:
On Error Resume Next
fndLast = rng.Find(What:="*", _
After:=rng.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
Case 2:
On Error Resume Next
fndLast = rng.Find(What:="*", _
After:=rng.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
Case 3:
On Error Resume Next
lrw = rng.Find(What:="*", _
After:=rng.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
On Error Resume Next
lcol = rng.Find(What:="*", _
After:=rng.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
On Error Resume Next
fndLast = rng.Parent.Cells(lrw, lcol).Address(False, False)
If Err.Number > 0 Then
fndLast = rng.Cells(1).Address(False, False)
Err.Clear
End If
On Error GoTo 0
End Select
End Function
I have a worksheet which contains the details of the each product.
Here i have crested a button (ADD), by clicking on it i want to copy all the details of the CONTROL POWER TRANSFORMERS block and copy it to below (i mean copy it from B20).
I have written a code to pinpoint the CTPT (which is the unique id for that product) keeping it as a reference i have copied whole block till the row ends using the below code.
Set cF = .Find(what:="CTPT", _
lookat:=xlPart, searchorder:=xlByRows, searchdirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
num = cF.Address ' Here we will the get the cell address of CTPT ($A$14)
WsEPC.Range(cF.Offset(-1, 3), cF.Offset(-1, 1).End(xlDown)).Copy
Now while pasting the cell i need to do couple of things
I need to insert an row by finding the cell address of the clicked button
Paste the copied Data
Code any one help me out in achieving these couple of task.
Any help is Appreciated!
Sub test_Karthik()
Dim WbEPC As Workbook, _
WbCPT As Workbook, _
WsEPC As Worksheet, _
WsCPT As Worksheet, _
FirstAddress As String, _
WriteRow As Long, _
cF As Range, _
num As String
Set WbEPC = Workbooks("EPC 1.xlsx")
Set WbCPT = Workbooks("Control Power Transformers.xlsm")
Set WsEPC = WbEPC.Sheets("Sheet1")
Set WsCPT = WbCPT.Sheets("Sheet2")
With WsEPC
.Activate
With .Range("A1:A10000")
'First, define properly the Find method
Set cF = .Find(What:="CTPT", _
After:=ActiveCell, _
LookIn:=xlValues, _
Lookat:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False, _
SearchFormat:=False)
'If there is a result, keep looking with FindNext method
If Not cF Is Nothing Then
FirstAddress = cF.Address
Do
num = cF.Address ' Here we will the get the cell address of CTPT ($A$14)
WsEPC.Range(cF.Offset(0, 1).End(xlUp), cF.Offset(0, 3).End(xlDown)).Copy
WriteRow = WsCPT.Range("E" & WsCPT.Rows.Count).End(xlUp).Row + 1
WsCPT.Range("E" & WriteRow).PasteSpecial (xlPasteValues)
cF.EntireRow.Insert xlDown, False
Set cF = .FindNext(cF)
'Look until you find again the first result
Loop While Not cF Is Nothing And cF.Address <> FirstAddress
End If
End With
End With
End Sub
Private Sub CommandButton21_Click()
Dim WbEPC As Workbook, _
WbCPT As Workbook, _
WsEPC As Worksheet, _
WsCPT As Worksheet, _
FirstAddress As String, _
WriteRow As Long, _
cF As Range, _
num As String
Set WbEPC = Workbooks("EPC 1.xlsm")
Set WbCPT = Workbooks("Control Power Transformers.xlsm")
Set WsEPC = WbEPC.Sheets("Sheet1")
Set WsCPT = WbCPT.Sheets("Sheet1")
Dim b As Object, RowNumber As Integer
Set b = ActiveSheet.Shapes("CommandButton21")
With b.TopLeftCell
RowNumber = .Row
End With
Rows(RowNumber + 1 & ":" & RowNumber + 1).Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
With WsEPC
.Activate
With .Range("A1:A10000")
Set cF = .Find(what:="CTPT", _
lookat:=xlPart, searchorder:=xlByRows, searchdirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
num = cF.Address ' Here we will the get the cell address of CTPT ($A$14)
WsEPC.Range(cF.Offset(-1, 3), cF.Offset(-1, 1).End(xlDown)).Copy
WsEPC.Range("B" & RowNumber + 1).Select
Selection.Insert Shift:=xlDown
Application.CutCopyMode = False
End With
End With
MsgBox " Successfully added the product to EPC"
End Sub
When I am debugging a excel-vba program I came to know my data range is not completely selected.
Below picture shows my data's model and my problem.
I used this code to select the whole range. But this is not working properly.
Dim rngTemp As Range
Set rngTemp = Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious)
With rngTemp
Please help me by giving the code for selecting the whole range as given in the figure above.
In your code you are searching by xlByRows. And hence you are getting the address of the last cell which has data which is G7.
Further to my comment, Is this what you are trying?
Sub Sample()
Dim lastrow As Long, lastcol As Long
Dim rng As Range
With Sheets("Sheet1") '<~~ Change this to the relevant sheet
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lastrow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
lastcol = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
Else
lastrow = 1: lastcol = 1
End If
Set rng = .Range("A1:" & _
Split(.Cells(, lastcol).Address, "$")(1) & _
lastrow)
MsgBox rng.Address
End With
End Sub
PLEASE BE AWARE THAT METHOD BELOW IS NOT RELIABLE IN SOME CASES. I WILL LEAVE THIS ANSWER HERE AS A BAD EXAMPLE. FOR DETAILED INFORMATION PLEASE SEE #SiddharthRout 'S EXPLANATION IN THIS LINK
I would use following code to find used range instead of looking for "*" in the cell value:
Sub SelectRange()
Dim LastRow As Long
Dim LastColumn As Long
Dim aWB As Workbook
Dim aWS As Worksheet
Set aWB = ActiveWorkbook
Set aWS = aWB.ActiveSheet '<-You can change sheet name like aWB.sheets("SheetName")
With aWS.UsedRange
LastRow = .Rows(.Rows.Count).Row
LastColumn = .Columns(.Columns.Count).Column
End With
aWS.Range(Cells(1, 1), Cells(LastRow, LastColumn)).Select '<---Cells(1, 1) is the starting cell of range)
End Sub
I have a range of cells in Excel that is more than one column wide and more than one row long. Some of the cells are blank. I would like to merge (using VBA) the non-blank cells into a list, remove the duplicates, and sort alphabetically.
For example, given this input (where a dash designates an empty cell for the purpose of this question):
- - A D -
C - - A -
- - B - D
- - - - -
A - - E -
The following sorted output is produced:
A
B
C
D
E
As the example input shows, some of the rows and columns in the range may contain all empty cells.
Here is one way to do it.
CODE
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim LastRow As Long, lastCol As Long, i as Long
Dim Rng As Range, aCell As Range
Dim MyCol As New Collection
'~~> Change this to the relevant sheet name
Set ws = Sheets("Sheet21")
With ws
LastRow = .Cells.Find(What:="*", After:=.Range("A1"), _
Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, MatchCase:=False).Row
lastCol = .Cells.Find(What:="*", After:=.Range("A1"), _
Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, MatchCase:=False).Column
Set Rng = .Range("A1:" & Split(.Cells(, lastCol).Address, "$")(1) & LastRow)
'Debug.Print Rng.Address
For Each aCell In Rng
If Not Len(Trim(aCell.Value)) = 0 Then
On Error Resume Next
MyCol.Add aCell.Value, """" & aCell.Value & """"
On Error GoTo 0
End If
Next
.Cells.ClearContents
For i = 1 To MyCol.Count
.Range("A" & i).Value = MyCol.Item(i)
Next i
'~~> OPTIONAL (In Case you want to sort the data)
.Columns(1).Sort Key1:=.Range("A1"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
End With
End Sub
SNAPSHOTS
FOLLOWUP
I just realized that adding 3 lines more makes this code even faster than the above code.
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim LastRow As Long, lastCol As Long, i As Long
Dim Rng As Range, aCell As Range, delRange As Range '<~~ Added This
Dim MyCol As New Collection
'~~> Change this to the relevant sheet name
Set ws = Sheets("Sheet1")
With ws
'~~> Get all the blank cells
Set delRange = .Cells.SpecialCells(xlCellTypeBlanks) '<~~ Added This
'~~> Delete the blank cells
If Not delRange Is Nothing Then delRange.Delete '<~~ Added This
LastRow = .Cells.Find(What:="*", After:=.Range("A1"), _
Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, MatchCase:=False).Row
lastCol = .Cells.Find(What:="*", After:=.Range("A1"), _
Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, MatchCase:=False).Column
Set Rng = .Range("A1:" & Split(.Cells(, lastCol).Address, "$")(1) & LastRow)
'Debug.Print Rng.Address
For Each aCell In Rng
If Not Len(Trim(aCell.Value)) = 0 Then
On Error Resume Next
MyCol.Add aCell.Value, """" & aCell.Value & """"
On Error GoTo 0
End If
Next
.Cells.ClearContents
For i = 1 To MyCol.Count
.Range("A" & i).Value = MyCol.Item(i)
Next i
'~~> OPTIONAL (In Case you want to sort the data)
.Columns(1).Sort Key1:=.Range("A1"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
End With
End Sub