Two VBA codes needed to paste in same unused row - vba

I need these two sets of VBA to paste on same line instead of one line below each other.The problem is they both look for an unused row, which is needed, but they should be on the same unused row. Thanks.
Sub Macro10()
Dim refTable As Variant, trans As Variant
refTable = Array("A = B4", "B = B5", "C = J5")
Dim Row As Long
Row = Worksheets("Customer List").UsedRange.Rows.Count + 1
For Each trans In refTable
Dim Dest As String, Field As String
Dest = Trim(Left(trans, InStr(1, trans, "=") - 1)) & Row
Field = Trim(Right(trans, Len(trans) - InStr(1, trans, "=")))
Worksheets("Customer List").Range(Dest).Value = Worksheets("Order Entry").Range(Field).Value
Next
End Sub
Private Sub CommandButton1_Click()
Application.ScreenUpdating = False
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Set copySheet = Worksheets("Order Entry")
Set pasteSheet = Worksheets("Customer List")
copySheet.Range("A8:K22").Copy
pasteSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 3).PasteSpecial xlPasteValues
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
Here is the Macro that Calls both of these macros.
Sub SUBMIT()
Call Macro10
Call CommandButton1_Click
Call Check
Call Macro6
Call Macro12
End Sub

One solution is to create a function that funds the row and save the as a variable. Create a function that saves the row as an integer and use this value in both subs.
Function findEmptyRow() As Integer
Row = Worksheets("Customer List").UsedRange.Rows.Count + 1
End Function
Sub SUBMIT()
row = findEmptyRow()
Call Macro10(row)
Call CommandButton1_Click(row)
Call Check
Call Macro6
Call Macro12
End Sub
Amend Macro10 so it can accept variables
Sub Macro10(row As Integer)
Dim refTable As Variant, trans As Variant
refTable = Array("A = B4", "B = B5", "C = J5")
For Each trans In refTable
Dim Dest As String, Field As String
Dest = Trim(Left(trans, InStr(1, trans, "=") - 1)) & row
Field = Trim(Right(trans, Len(trans) - InStr(1, trans, "=")))
Worksheets("Customer List").Range(Dest).Value = Worksheets("Order Entry").Range(Field).Value
Next
End Sub
Then similar for CommandButton1_Click. This used a different method to find the empty row so it has to be adjusted slightly.
Private Sub CommandButton1_Click(row As Integer)
Application.ScreenUpdating = False
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Set copySheet = Worksheets("Order Entry")
Set pasteSheet = Worksheets("Customer List")
copySheet.Range("A8:K22").Copy
pasteSheet.Cells(row, 1).PasteSpecial xlPasteValues
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub

Related

Mapping table with multiple items

I have a mapping table which I use for matching headers of two separate sheets (Sheet1 and Sheet2).
But what if I have something like this (3 columns in the left part, 2 columns in the right):
Basically I want POS1 2019 EMP1 to be equal to HR DEPARTMAENT Employee1 and so on.
Sheet1,
Sheet2,
Mapping
Any ideas how can I do it?
Thank you in advance! :)
Public Sub test()
Application.ScreenUpdating = False
stack "Sheet1", "Sheet2", "Mapping"
Application.ScreenUpdating = True
End Sub
Public Sub stack(ByVal Sheet1 As String, ByVal Sheet2 As String, ByVal
Mapping As String)
Dim rng As Range, trgtCell As Range, src As Worksheet, trgt As
Worksheet, helper As Worksheet
Dim rngSrc As Range, rngDest As Range
Dim sht As Worksheet
Set src = Worksheets("Sheet1")
Set trgt = Worksheets("Sheet2")
Set helper = Worksheets("Mapping")
With src
For Each rng In Intersect(.Rows(3), .UsedRange).SpecialCells(xlCellTypeConstants)
Dim lkup As Variant
With helper
lkup = Application.VLookup(rng.Value, .Range("D13:E" & .Cells(.Rows.Count, "D").End(xlUp).Row), 2, False)
End With
If Not IsError(lkup) Then
Set trgtCell = trgt.Range("$B$2:$F$7").Find(lkup, LookIn:=xlValues, lookat:=xlWhole)
If Not trgtCell Is Nothing Then
.Range(rng.Offset(1), .Cells(.Rows.Count, rng.Column).End(xlUp)).Copy
With trgt
.Range(Split(trgtCell.Address, "$")(1) & 3).PasteSpecial
End With
End If
End If
Next rng
End With
End Sub
I think dictionaries are the data structure most suited to this type of problem.
Be aware, to use dictionaries in VBA you need to set a reference to the Scripting Runtime library.
Tools->Reference-> Microsoft Scripting Runtime
Here is some code that works on the example you provided:
Public Sub test()
Application.ScreenUpdating = False
stack2 "Sheet1", "Sheet2", "Mapping"
Application.ScreenUpdating = True
End Sub
Public Sub stack(ByVal Sheet1 As String, ByVal Sheet2 As String, ByVal Mapping As String)
Dim rng As Range, src As Worksheet, trgt As Worksheet, helper As Worksheet
Dim sht As Worksheet
Dim dctCol As Dictionary, dctHeader As Dictionary
Dim strKey1 As String, strKey2 As String
Dim strItem As String, col As Integer
Set src = Worksheets(Sheet1)
Set trgt = Worksheets(Sheet2)
Set helper = Worksheets(Mapping)
'build a dictionary to lookup column based on 3 rows of headers
Set dctCol = New Dictionary
arr1 = src.Range("A1:F7") 'arrays are way faster than ranges
For j = 2 To UBound(arr1, 2) 'loop over data from columns B-F
strKey1 = Trim(arr1(1, j)) & "," & Trim(arr1(2, j)) & "," & Trim(arr1(3, j)) 'comma delimit string
dctCol(strKey1) = j 'j is the column number
Next
'build a dictionary to translate 2 headers to 3 headers
Set dctHeader = New Dictionary
arrHelp = helper.Range("A2:E6")
For i = 1 To UBound(arrHelp)
strKey2 = Trim(arrHelp(i, 4)) & "," & Trim(arrHelp(i, 5)) '2 header key
strItem = Trim(arrHelp(i, 1)) & "," & Trim(arrHelp(i, 2)) & "," & Trim(arrHelp(i, 3))
dctHeader(strKey2) = strItem
Next
'update sheet2 with numbers from sheet1
arr2 = trgt.Range("A1:F6")
For j = 2 To 5
'work backwards to find the column
strKey2 = Trim(arr2(1, 2)) & "," & Trim(arr2(2, j)) '2 headers
strKey1 = dctHeader(strKey2)
col = dctCol(strKey1)
'update the data for arr2
For i = 3 To 6
arr2(i, j) = arr1(i + 1, col)
Next
Next
'write it back to spreadsheet
trgt.Range("M10").Resize(UBound(arr2), UBound(arr2, 2)) = arr2
End Sub
Please, try the next adapted code.
Public Sub test()
Application.ScreenUpdating = False
stack "Sheet1", "Sheet2", "Mapping"
Application.ScreenUpdating = True
End Sub
Public Sub stack(ByVal Sheet1 As String, ByVal Sheet2 As String, ByVal Mapping As String)
Dim rng As Range, trgtCell As Range, src As Worksheet, trgt As Worksheet, helper As Worksheet
Dim rngSrc As Range, rngDest As Range
Dim sht As Worksheet
Set src = Worksheets(Sheet1)
Set trgt = Worksheets(Sheet2)
Set helper = Worksheets(Mapping)
With src
For Each rng In Intersect(.Rows(3), .UsedRange).SpecialCells(xlCellTypeConstants)
Dim lkup As Variant
With helper
lkup = Application.VLookup(rng.Value, .Range("C2:E" & .Cells(.Rows.Count, "C").End(xlUp).Row), 3, False)
End With
If Not IsError(lkup) Then
Set trgtCell = trgt.Range("$B$2:$F$7").Find(lkup, LookIn:=xlValues, lookat:=xlWhole)
Debug.Print trgtCell.Address
If Not trgtCell Is Nothing Then
With trgt
.Range(trgtCell.Offset(1), .Cells(.Rows.Count, trgtCell.Column).End(xlUp)).Copy
End With
.Range(Split(trgtCell.Address, "$")(1) & 4).PasteSpecial
End If
End If
Next rng
End With
End Sub
Please, also correct the sub calling the second one. You mixed "Shee2" with "Sheet1" there...
Please, test it and send some feedback.

How to check for 2 different values and delete the text where either of these values are found?

I want to find "Ext" and "/" in a column of data and delete all the text after and including those characters
If it doesn't find those characters in my data then exit the sub
I can do them separately but I definitely over complicated it, there must be an easier way
The data column will also have blanks in so I have to avoid blank cells and check the whole range of data
Code
Sub DeleteAfterText()
Dim rngFoundCell As Range
Set rngFoundCell = Sheets("User Load").Range("E1:E3000").Find(What:="Ext")
'This is checking to see if the range contains EXT, if not it exits the sub'
If rngFoundCell Is Nothing Then 'If no cell in the range has an ' then exist sub
Exit Sub
Else
Worksheets("User Load").Range("E1000").Select 'Start from bottom'
Selection.End(xlUp).Select 'This selects the bottom to the top'
Do Until ActiveCell.Value = "Phone Number" 'This does the change until it reaches the header name'
If ActiveCell.Value = "" Then 'If the cell is blank it skips it as there is no action after the then'
Else
ActiveCell = Split(ActiveCell.Value, "Ext")(0)
'ActiveCell = Split(ActiveCell.Value, "/")(0)
End If
ActiveCell.Offset(-1, 0).Select
Loop
End If
End Sub
Sub DeleteAfterText2()
Dim rngFoundCell As Range
Set rngFoundCell = Sheets("User Load").Range("E1:E3000").Find(What:="/")
'This is checking to see if the range contains EXT, if not it exits the sub'
If rngFoundCell Is Nothing Then 'If no cell in the range has an ' then exist sub
Exit Sub
Else
Worksheets("User Load").Range("E1000").Select 'Start from bottom'
Selection.End(xlUp).Select 'This selects the bottom to the top'
Do Until ActiveCell.Value = "Phone Number" 'This does the change until it reaches the header name'
If ActiveCell.Value = "" Then 'If the cell is blank it skips it as there is no action after the then'
Else
ActiveCell = Split(ActiveCell.Value, "/")(0)
End If
ActiveCell.Offset(-1, 0).Select
Loop
End If
End Sub
This code should work. It is simple to read and easy to understand.
Option Explicit
'The calling Sub
Sub main()
DeleteTextFromColumn ActiveSheet.Range("E1:E3000")
End Sub
Sub DeleteTextFromColumn(ByRef inRange As Range)
Dim cCell As Range
Dim intPos1 As Integer
Dim intPos2 As Integer
Dim strTemp As String
Dim strOut As String
'You can specify which column if more than one column is provided to the
' subroutine. Ex: Range("E1:F3000")
For Each cCell In inRange.Columns(1).Cells
strTemp = cCell.Value
'gets the position of "ext" (case insensitive)
intPos1 = InStr(LCase(strTemp), "ext")
'gets the position of "/"
intPos2 = InStr(strTemp, "/")
strOut = strTemp
If intPos1 > 1 Then
strOut = Mid(strTemp, 1, intPos1 - 1)
ElseIf intPos2 > 1 Then
strOut = Mid(strTemp, 1, intPos2 - 1)
End If
'Outputs the results
cCell.Value = strOut
Next
End Sub
It's best to break out repeated code into a sub which has parameters for the variable parts of the operation.
You can do something like this:
Sub Tester()
Dim theRange As Range
Set theRange = Sheets("User Load").Range("E1:E3000")
RemoveTextAfter theRange, "Ext"
RemoveTextAfter theRange, "/"
End Sub
Sub RemoveTextAfter(rng As Range, findWhat As String)
Dim f As Range
If Len(findWhat) = 0 Then Exit Sub
Set f = rng.Find(What:="Ext", lookat:=xlPart)
Do While Not f Is Nothing
f.Value = Split(f.Value, findWhat)(0)
Set f = rng.Find(What:="Ext", lookat:=xlPart)
Loop
End Sub
I'm going to give you two answers for the price of one. :)
At its root, the basic logic you need to figure out if a substring exists in a given string is a standard part of VBA in the InStr function. Using this, you can break out your logic to check a cell's value and (conditionally) delete the remainder of the string into a function like this:
Private Function DeleteTextAfter(ByVal contents As String, _
ByVal token As String) As String
'--- searches the given string contents and if it finds the given token
' it deletes the token and all following characters
DeleteTextAfter = contents
Dim pos1 As Long
pos1 = InStr(1, contents, token, vbTextCompare)
If pos1 > 0 Then
DeleteTextAfter = Left(contents, pos1 - 1)
End If
End Function
Notice here that using the function created above, we don't need to use Range.Find at all.
Once you have that, your top-level logic consists of setting up the range to search. In all of my code, I explicitly create objects to reference the workbook and worksheet so that I can keep things straight. In a simple example like this, it may seem like overkill, but the habit comes in handy when your code gets more involved. So I set up the range like this
Dim thisWB As Workbook
Dim userLoadWS As Worksheet
Set thisWB = ThisWorkbook
Set userLoadWS = thisWB.Sheets("User Load")
Dim searchRange As Range
Set searchRange = userLoadWS.Range("E1:E3000")
Now the loop just goes through each cell and gets a (potentially) updated value.
Dim cell As Variant
For Each cell In searchRange
If Not cell.value = vbNullString Then
Debug.Print cell.Address & " = " & cell.value
cell.value = DeleteTextAfter(cell.value, "Ext")
cell.value = DeleteTextAfter(cell.value, "/")
End If
Next cell
So your whole solution looks like this:
Option Explicit
Public Sub TestDirectlyFromRange()
Dim thisWB As Workbook
Dim userLoadWS As Worksheet
Set thisWB = ThisWorkbook
Set userLoadWS = thisWB.Sheets("User Load")
Dim searchRange As Range
Set searchRange = userLoadWS.Range("E1:E3000")
Dim cell As Variant
For Each cell In searchRange
If Not cell.value = vbNullString Then
Debug.Print cell.Address & " = " & cell.value
cell.value = DeleteTextAfter(cell.value, "Ext")
cell.value = DeleteTextAfter(cell.value, "/")
End If
Next cell
End Sub
Private Function DeleteTextAfter(ByVal contents As String, _
ByVal token As String) As String
'--- searches the given string contents and if it finds the given token
' it deletes the token and all following characters
DeleteTextAfter = contents
Dim pos1 As Long
pos1 = InStr(1, contents, token, vbTextCompare)
If pos1 > 0 Then
DeleteTextAfter = Left(contents, pos1 - 1)
End If
End Function
But wait, there's more!!
You're iterating over 3,000 rows of data. That can get to be slow if all those rows are filled or if you increase the number of rows to search. To speed up the search, the answer is to copy the data in the range to a memory-based array first, modify any of the data, then copy the results back. This example uses the same Function DeleteTextAfter as above and is much quicker. Use whichever one fits your situation best.
Public Sub TestRangeInArray()
Dim thisWB As Workbook
Dim userLoadWS As Worksheet
Set thisWB = ThisWorkbook
Set userLoadWS = thisWB.Sheets("User Load")
'--- create the range and copy into a memory array
Dim searchRange As Range
Dim searchData As Variant
Set searchRange = userLoadWS.Range("E1:E3000")
searchData = searchRange.value
Dim i As Long
For i = LBound(searchData, 1) To UBound(searchData, 1)
If Not searchData(i, 1) = vbNullString Then
searchData(i, 1) = DeleteTextAfter(searchData(i, 1), "Ext")
searchData(i, 1) = DeleteTextAfter(searchData(i, 1), "/")
End If
Next i
'--- now copy the modified array back to the worksheet range
searchRange.value = searchData
End Sub

Copy data from one sheet to another in reverse order using vba

I have two sheets in my excel PullData and AllStocks. I would like to copy data from PullData column A and paste the values reverse order into other sheet AllStocks.
Currently, I am using OFFSET function to perform it. But I see a performance issue while running large data set using this method. Is there any better way I can perform this task ?
My CUrrent Code :
Sub GetData()
Dim Main As Worksheet
Dim PullData As Worksheet
Dim AllStocks As Worksheet
Dim i,m As Integer
Set RawImport = Workbooks("vwap.xlsm").Sheets("RawImport")
Set PullData = Workbooks("vwap.xlsm").Sheets("PullData")
m = PullData.Cells(Rows.Count, "A").End(xlUp).Row
For i = 3 To m
AllStocks.Range("A2:A" & i).Formula = "=OFFSET(PullData!$A$" & m & ",-(ROW(PullData!A1)-1),0)"
Next i
End Sub
no loop code:
Option Explicit
Sub GetData()
Dim pullDataVals As Variant
With Workbooks("vwap.xlsm")
With .Sheets("PullData")
pullDataVals = Split(StrReverse(Join(Application.Transpose(.Range("A3", .Cells(.Rows.Count, "A").End(xlUp)).Value), ",")), ",")
End With
.Sheets("RawImport").Range("A2").Resize(UBound(pullDataVals) + 1).Value = Application.Transpose(pullDataVals)
End With
End Sub
just check your sheets names: in your question you're speaking about "PullData and AllStocks" but in your code some RawImport sheet is featuring...
or, in a super compressed style:
Sub GetData()
With Workbooks("vwap.xlsm").Sheets("PullData")
With .Range("A3", .Cells(.Rows.Count, "A").End(xlUp))
.Parent.Parent.Sheets("RawImport").Range("A2").Resize(.Rows.Count).Value = Application.Transpose(Split(StrReverse(Join(Application.Transpose(.Value), ",")), ","))
End With
End With
End Sub
should your data in PullData be a more than one character string or more than one digit number, to prevent what Gary's Student remarked, you could use ArrayList object and its Reverse method:
Sub GetData()
Dim arr As Object
Dim cell As Range
Set arr = CreateObject("System.Collections.Arraylist")
With Workbooks("vwap.xlsm")
With .Sheets("PullData")
For Each cell In .Range("A3", .Cells(.Rows.Count, "A").End(xlUp))
arr.Add cell.Value
Next
End With
arr.Reverse
.Sheets("RawImport").Range("A2").Resize(arr.Count) = Application.Transpose(arr.toarray)
End With
End Sub
This solution applies the INDEX formula to a temporary Name.
Sub Range_ReverseOrder()
Const kFml As String = "=INDEX(_Src,#RowsSrc+#RowTrg-ROW(),1)"
Dim nmSrc As Name, rgTrg As Range
Dim lRows As Long, sFml As String
Rem Set Objects
With Workbooks("vwap.xlsm")
lRows = .Worksheets("PullData").Cells(Rows.Count, 1).End(xlUp).Row
Set nmSrc = .Names.Add(Name:="_Src", _
RefersTo:=.Worksheets("PullData").Cells(2, 1).Resize(-1 + lRows, 1))
.Names("_Src").Comment = "Range_ReverseOrder"
Set rgTrg = .Worksheets("RawImport").Cells(2, 1).Resize(-1 + lRows, 1)
End With
Rem Set Formula
sFml = kFml
sFml = Replace(sFml, "#RowsSrc", nmSrc.RefersToRange.Rows.Count)
sFml = Replace(sFml, "#RowTrg", rgTrg.Row)
Rem Apply Formula
With rgTrg
.Offset(-1).Resize(1).Value = "Reverse.Order"
.Formula = sFml
.Value2 = .Value2
End With
Rem Delete Temporary Name
nmSrc.Delete
End Sub

Using endxldown function to copy and paste unlimited data

I'm trying to copy and paste data from one workbook into another. This function works when the range is static, but I cannot get it to be dynamic. I know the endxldown function is for this, but how would I work it into my code:
Private Sub CommandButton21_Click()
Dim itemName As String
Dim itemPrice As Single
Dim myData As Workbook
Worksheets("Sheet1").Select
itemName = Range("A2")
Worksheets("Sheet1").Select
itemPrice = Range("B2")
Set myData = Workbooks.Open("C:\Users\Iraj.Masud\Desktop\testing\Master.xlsm")
Worksheets("Sheet1").Select
Worksheets("Sheet1").Range("A1").Select
RowCount = Worksheets("Sheet1").Range("A1").CurrentRegion.Rows.Count
With Worksheets("Sheet1").Range("A1")
.Offset(RowCount, 0) = itemName
.Offset(RowCount, 1) = itemPrice
End With
myData.Save
End Sub
My edits are highlighted in the image below. When I ran the macro, I received an object variable or with block variable not set.
Code with Error
I'd guess:
With Worksheets("Sheet1")
With .Range("A" & .Rows.Count).end(xlUp)
.Offset(1, 0) = itemName
.Offset(1, 1) = itemPrice
End With
End With
try this, (I cleaned up your code), see also the instruction that sets a value to rowcount
Private Sub CommandButton21_Click()
Dim rowcount As Long
Dim myData As Workbook
With Worksheets("Sheet1")
.Range("A2:B" & .Cells(.Rows.Count, 1).End(xlUp).Row).Copy
End With
Set myData = Workbooks.Open("C:\Users\Iraj.Masud\Desktop\testing\Master.xlsm")
With myData.Worksheets("Sheet1")
rowcount = .Cells(.Rows.Count, 1).End(xlUp).Row + 1
.Cells(rowcount, 1).Paste
End With
myData.Save
End Sub
Use End(xlUp) from the bottom to capture the last row, this is better than using xlDown because the latter will capture the first empty row, not the last row.
Removing all the unnecessary Select stuff and using arrays, your code can be reduced to this:
Private Sub CommandButton21_Click()
With Workbooks.Open("C:\Users\Iraj.Masud\Desktop\testing\Master.xlsm").Sheets("Sheet1")
.Cells(.Rows.Count, "A").End(xlUp).Offset(1).Resize(1, 2).Value = _
ThisWorkbook.Sheets("Sheet1").Range("A2:B2").Value2
.Parent.Close True
End With
End Sub
Note that all references are explicit, there is no implicit reference to whichever workbook or worksheet is active. This usually results in safer code.
EDIT
If you want to copy all A:B data from the source, use this:
Private Sub CommandButton21_Click()
Dim src as Range
Set src = ThisWorkbook.Sheets("Sheet1").Range("A2", ThisWorkbook.Sheets("Sheet1").Range("B999999").End(xlUp)
With Workbooks.Open("C:\Users\Iraj.Masud\Desktop\testing\Master.xlsm").Sheets("Sheet1")
.Cells(.Rows.Count, "A").End(xlUp).Offset(1) _
.Resize(src.Rows.Count, src.Columns.Count).Value = src.Value2
.Parent.Close True
End With
End Sub
Private Sub CommandButton21_Click()
Dim itemName As String
Dim itemPrice As Single
Dim wbData As Workbook
Dim wsData As Worksheet
Dim newData As Range
With ThisWorkbook.Worksheets("Sheet1") '<~defines that we are working on sheet1
itemName = .Range("A2") '<~gets the itemname
itemPrice = .Range("B2") '<~gets the itemprice
End With
Set wbData = Workbooks.Open("C:\Users\Iraj.Masud\Desktop\testing\Master.xlsm") '<~opens then workbook
Set wsData = wbData.Worksheets("Sheet1") '<~sets the worksheet
Set newData = wsData.Range("A1048576").End(xlUp).Offset(1, 0) '<~locate last cell and offset 1 row below
With newData '<~defines that we are working with the cell below the last non-blank cell
.Offset(0, 0).Value = itemName '<~passes the item name
.Offset(0, 1).Value = itemPrice '<~passes the item price
End With
Set newData = Nothing '<~post procedure cleaning
Set wsData = Nothing '<~post procedure cleaning
wbData.Save '<~save
wbData.Close
End Sub
This might be a chunky code. But IMO, this is flexible in case you want to change some part/s of the code.

Need help trimming spaces out of column

I am trying to figure out how to loop through the first column of my worksheet and take out the spaces so I can use VLOOKUP. Not sure how to do it in VBA. Here is what I have:
I can't figure out why it does not go onto the next sheet now? I can't just cycle through all of the sheets since they are different.
Sub trima()
Dim x As Integer
Dim numrows As Long
numrows = Range("A1",Range("A1").End(xlDown)).Rows.Count
Range("A1").Select
For x = 1 To numrows
Application.WorksheetFunction.trim (ActiveCell)
ActiveCell.Offset(1, 0).Select
Next
End Sub
Here you go:
Sub TrimA()
Dim v
v = [transpose(transpose(trim(a1:index(a:a,match("",a:a,-1)))))]
[a1].Resize(UBound(v)) = v
End Sub
UPDATE
If you want to update multiple sheets, you can utilize the above like so:
Sub DoTrims()
Sheet1.Activate: TrimA
Sheet2.Activate: TrimA
'etc.
End If
The Trim function does not work like that.
Instead, try something like:
Sub trima()
Dim numrows As Long
Dim vItem as Variant
Dim i As Long
numrows = Range("A1",Range("A1").End(xlDown)).Rows.Count
Application.ScreenUpdating = False
With ActiveSheet
For i = 1 To numrows
vItem = .Range("A" & i)
If vItem <> vbNullString then .Range("A" & i) = Application.WorksheetFunction.Trim(vItem)
Next
End With
Application.ScreenUpdating = True
End Sub
The following code will loop through ALL worksheets in the Workbook and perform the same trim on values in Column A:
Sub trimA()
Dim ws As Excel.Worksheet
Dim i As Long, numrows As Long
Dim vItem As Variant
Application.ScreenUpdating = False
For Each ws In Worksheets
With ws
numrows = .Range("A1", .Range("A1").End(xlDown)).Rows.Count
For i = 1 To numrows
vItem = .Range("A" & i)
If vItem <> vbNullString Then .Range("A" & i) = Application.WorksheetFunction.Trim(vItem)
Next i
End With
Next
Application.ScreenUpdating = True
End Sub
Using the Range.TextToColumns method should quickly clear all cells containing leading/trailing spaces.
This procedure can quickly convert text-that-look-like-numbers to true numbers as well.
Dim c As Long
With Range("A1").CurrentRegion `<~~ set to the desired range of one or more columns
For c = 1 To .Columns.Count
.Columns(c).TextToColumns Destination:=.Columns(c), _
DataType:=xlFixedWidth, FieldInfo:=Array(0, 1)
Next c
End With
If the cells actually contain non-standard spacing like the non-breaking space (common on data copied from a web page) then other Range.Replace method should be added.