I want to create a macro to remove the space After the String in the range. Tried Trim and doesn't do anything [duplicate] - excel

This question already has answers here:
How to remove spaces from an entire Excel column using VBA?
(3 answers)
Closed 2 years ago.
I want to remove the extra spaces after the text "Denver Health " into "Denver Health" for the range in column A.
input:
Column A
"Denver Health Hospital "
"Pueblo Hospital "
output:
Column A
"Denver Health Hospital"
"Pueblo Hospital"
I have tried that code but it removes all the spaces
Sub SpaceKiller()
Worksheets("Sheet2").Columns("A").Replace _
what:=" ", _
Replacement:="", _
SearchOrder:=xlByColumns, _
MatchCase:=True
End Sub
Another attempt was
Sub trim()
Dim r As String
r = RTrim(Range("A2:A"))
End Sub

This will get the trailing spaces..
Sub TrimTrailingSpaces()
Dim LR As Long 'Use Long as Integer can only handle 32,767
Dim myRng As Range 'I am going to name the used range
Dim ws As Worksheet 'Declare worksheet as variable
Dim cll As Range
Set ws = ThisWorkbook.Worksheets("Sheet2") 'Want to be specific on the worksheet used
LR = ws.Cells(Rows.Count, 1).End(xlUp).Row 'Find the last row in Col A. Do not include the whole column of over 1 million cells
Set myRng = ws.Range(ws.Cells(2, 1), ws.Cells(LR, 1)) 'Declare the range used
For Each cll In myRng 'cll is a Cell in a Collection of Cells in a Range that we defined
cll = RTrim(cll) 'Looping through, modify each cell
Next cll 'Go to the next Cell
End Sub

You can write own function to delete all additional spaces from string. allow only one space
Function Remove2Spaces(text As String) As String
Dim i_Len As Integer
Dim ReturnText As String
i_Len = Len(text)
For i = 1 To i_Len
If Mid(text, i, 1) = " " Then
If Mid(text, i + 1, 1) = " " Then
text = Mid(text, 1, i) & Mid(text, i + 2)
i = i - 1
End If
End If
Next i
Remove2Spaces = text
End Function
to get result place inside sub like below
sub Test()
MsgBox Remove2Spaces(ActiveSheet.Range("A3"))
end sub

Related

How can I enter value in excle cell contain many words and search for in database

How can I enter value in excel cell contain many words and search for in database if any word in the search cell matched the words in database just appear for me
am trying to write code but the problem that the code search for one word only and if I write may words in cell the code doesn't work
Sub searchkey()
Dim i As Integer
Dim keyword As String
Dim findrow As Integer
Sheet1.Range("b5:b20").ClearContents
keyword = Sheets("Search").Range("B2").Value
findrow = Sheets("Database").Range("B30").End(xlUp).Row
Sheets("Database").Activate
For i = 2 To findrow
If Sheet2.Cells(i, 2) = keyword Then
Sheet2.Range(Cells(i, 2), Cells(i, 2)).Copy
Sheets("Search").Range("B20").End(xlUp).Offset(1, 0).PasteSpecial
End If
Next i
Sheet1.Activate
End Sub
You need to split the keyword into pieces (in below code, I've called them keywordpart) and search for each one:
Sub searchkey()
Dim i As Integer
Dim keyword As String, keywordpart As Variant
Dim findrow As Integer
Dim wsSearch As Worksheet
Dim wsDatabase As Worksheet
Set wsSearch = Sheets("Search")
Set wsDatabase = Sheets("Database")
wsSearch.Range("b5:b20").ClearContents
keyword = wsSearch.Range("B2").Value
findrow = wsDatabase.Range("B30").End(xlUp).Row
For Each keywordpart In Split(keyword, " ")
For i = 2 To findrow
If wsDatabase.Cells(i, 2) = keywordpart Then
wsDatabase.Range(Cells(i, 2), Cells(i, 2)).Copy
wsSearch.Range("B20").End(xlUp).Offset(1, 0).PasteSpecial
End If
Next i
Next
End Sub
I also took the liberty of tidying up your worksheet referencing - as you sometimes referenced them by name and other times by object name.

Drag formulas from Range with several variables, Error 1004

I have a task to drag formulas in several columns based on length of one specific column (which length can vary).
I managed to do it, but had to create new line of code for each range.
Sample of my Variant 1:
Sub DragRows()
Dim LastRowEPS As Integer
Dim tr As Range
Set tr = Range("A14:G" & LastRowEPS)
Range("A14:G14").Select
Selection.AutoFill Destination:=tr, Type:=xlFillDefault
Set tr = Range("I14:K" & LastRowEPS)
Range("I14:K14").Select
Selection.AutoFill Destination:=tr, Type:=xlFillDefault
End Sub
I want to optimize my code and include several variable ranges in one line of code.
Here is my Variant 2:
Sub DragRows()
Dim LastRowEPS As Integer
Dim tr As Range
LastRowEPS = Sheet1.Cells(14, 12).End(xlDown).Row
Set tr = Range("A14:G" & LastRowEPS & ", I14:K" & LastRowEPS & ", M14:N" & LastRowEPS & ", P14:P" & LastRowEPS)
Range("A14:G14,I14:K14,M14:N14,P14:P14").Select
Selection.AutoFill Destination:=tr, Type:=xlFillDefault
End Sub
The selection process works, and tr.Range is defined properly, but VBA autofill shows Error:
Run-time error '1004': AutoFill method of Range class failed
Is it possible to include several variable ranges as destination of autofill or any other way to optimize my code?
Actually i found out a solution, which i was lookin for. Maybe for someone it will be helpful. .AutoFill is bad with multiple ranges, that's why simple use of .FillDown is an answer here:
Sub DragRows()
Dim LastRowEPS As Integer
Dim tr As Range
LastRowEPS = Sheet1.Cells(14, 12).End(xlDown).Row
Set tr = Sheet1.Range("A14:G" & LastRowEPS & ", I14:K" & LastRowEPS & ", M14:N" & LastRowEPS & ", P14:P" & LastRowEPS)
tr.FillDown
End Sub
AutoFill, Formula, FillDown
The following shows two different approaches.
OP already revealed the superior solution, which is covered in the second procedure.
Three Solutions (Inferior: Applied to Four Ranges)
Sub dragRows()
' Define constants.
Const FirstRow As Long = 14
Const LastRowCol As Long = 12
Dim Cols As Variant
Cols = Array("A:G", "I:K", "M:N", "P")
' In worksheet...
With Sheet1
' Determine Rows Count.
Dim RowsCount As Long
RowsCount = .Cells(FirstRow, LastRowCol).End(xlDown).Row - FirstRow + 1
' Declare variables
Dim rng As Range
Dim n As Long
' Define and fill each range.
For n = LBound(Cols) To UBound(Cols)
Set rng = .Columns(Cols(n)).Rows(FirstRow)
' Choose one of the following solutions
rng.AutoFill Destination:=rng.Resize(RowsCount), Type:=xlFillDefault
'rng.Resize(RowsCount).Formula = rng.Formula
'rng.Resize(RowsCount).FillDown
Next n
End With
End Sub
FillDown Solution (Superior: Applied to One Range)
Sub dragRowsFillDown()
' Define constants.
Const FirstRow As Long = 14
Const LastRowCol As Long = 12
Dim Cols As Variant
Cols = Array("A:G", "I:K", "M:N", "P")
' In worksheet...
With Sheet1
' Determine Rows Count.
Dim RowsCount As Long
RowsCount = .Cells(FirstRow, LastRowCol).End(xlDown).Row - FirstRow + 1
' Declare variables
Dim rng As Range
Dim n As Long
' Define (non-contiguous) range.
For n = LBound(Cols) To UBound(Cols)
If Not rng Is Nothing Then
Set rng = Union(rng, .Columns(Cols(n)).Rows(FirstRow) _
.Resize(RowsCount))
Else
Set rng = .Columns(Cols(n)).Rows(FirstRow).Resize(RowsCount)
End If
Next n
End With
rng.FillDown
End Sub

Adding additional rows under a row, depending on the amount of used cells in a range

basically I need to split a cell that has a few values, seperated by a comma into more cells. Then i need to create the exact amount of the cells under the new cells to be able to transpose this range later to have a new table.
In the picture you can see an example of what I have and what I need. I needed to anonymyze the data. Also I have hundreds of rows that need to changed like the 2 in the example.
Ths is my current code:
Sub texttocolumns()
Dim rng As Range
Dim x As Integer
x = ActiveSheet.UsedRange.Rows.Count
For i = x - 2 To 1
Cells(2 + i, 8).texttocolumns _
Destination:=Cells(2 + i, 9), _
Comma:=True
k = Application.WorksheetFunction.CountA("A" & "2 + i"" & "":" & "AT1")
Cells(2 + i, 1).Rows(k).Insert
Next i
End Sub
I can't find my mistake at the moment, could someone please help me out? thanks!
Since the output result is posted to a different location the expensive task of inserting rows can be avoided.
Try this procedure, which also avoids working with the source range by generating from it two Arrays:
An array containing the fixed fields
An array containing the field that needs to be split
The Procedure:
Sub Range_Split_A_Field()
Dim wsTrg As Worksheet, rgOutput As Range
Dim aFld_1To5 As Variant, aFld_6 As Variant
Dim aFld As Variant
Dim lRow As Long, L As Long
lRow = 3
Set wsTrg = ThisWorkbook.Sheets("Sht(2)")
Application.Goto wsTrg.Cells(1), 1
With wsTrg.Cells(lRow, 1).CurrentRegion
Set rgOutput = .Rows(1).Offset(0, 10)
.Rows(1).Copy
rgOutput.PasteSpecial
Application.CutCopyMode = False
aFld_1To5 = .Offset(1, 0).Resize(-1 + .Rows.Count, 5).Value2
aFld_6 = .Offset(1, 5).Resize(-1 + .Rows.Count, 1).Value2
End With
lRow = 1
For L = 1 To UBound(aFld_1To5)
aFld = aFld_6(L, 1)
If aFld = vbNullString Then
rgOutput.Offset(lRow).Resize(1, 5).Value = WorksheetFunction.Index(aFld_1To5, L, 0)
rgOutput.Offset(lRow, 5).Resize(1, 1).Value = aFld
lRow = 1 + lRow
Else
aFld = Split(aFld, Chr(44))
aFld = WorksheetFunction.Transpose(aFld)
rgOutput.Offset(lRow).Resize(UBound(aFld), 5).Value = WorksheetFunction.Index(aFld_1To5, L, 0)
rgOutput.Offset(lRow, 5).Resize(UBound(aFld), 1).Value = aFld
lRow = lRow + UBound(aFld)
End If: Next
End Sub
Please see the following pages for a better understanding of the resources used:
Application.Goto Method (Excel)
With Statement
Range Object (Excel)
Chr Function
UBound Function
WorksheetFunction Object (Excel)
Would something like this work:
'A1 = A,B,C,D,E,F,G
'A2 = 1,2,3,4,5,6,7
'A3 = A!B!C!D!E!F!G
'Test procedure will result in:
'A - G in cells A1:A7
'1,2,3,4,5,6,7 in cell A8.
'A - G in cells A9:A15
Sub Test()
TextToColumns Sheet1.Range("A1")
TextToColumns Sheet1.Range("A9"), "!"
End Sub
Public Sub TextToColumns(Target As Range, Optional Delimiter As String = ",")
Dim rng As Range
Dim lCount As Long
Dim x As Long
'How many delimiters in target string?
lCount = Len(Target) - Len(Replace(Target, Delimiter, ""))
'Add the blank rows.
For x = 1 To lCount + 1
Target.Offset(1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Next x
'Split the string.
Target.TextToColumns Target, xlDelimited, xlTextQualifierNone, , , , , , True, Delimiter
'Use TRANSPOSE formula to paste to rows and then remove formula.
With Target.Offset(1).Resize(lCount + 1, 1)
.FormulaArray = "=TRANSPOSE(R" & Target.Row & "C:R" & Target.Row & "C" & lCount + 1 & ")"
.Value = .Value
End With
'Delete the original text string.
Target.EntireRow.Delete
End Sub
Edit:
To use from the Macro dialog box you could add this small procedure:
Public Sub Test()
Dim y As Long
y = ActiveSheet.UsedRange.Rows.Count
With ActiveSheet
For y = 5 To 1 Step -1
TextToColumns .Cells(y, 1)
Next y
End With
End Sub
Note: ActiveSheet.UsedRange.Rows.Count is a terrible way to find the last row.
See this thread: Error in finding last used cell in VBA

Excel VBA Range for all relevant cells

My macro creates a large text file by writing all the data from all sheets in the active workbook.
In each worksheet, it is necessary to determine a certain rectangular range of cells that would be saved in the text file. It's upper left corner would always be A1, but the lower right corner should be chosen so that the range includes all cells with any content (formatting does not matter).
I thought ws.Range("A1").CurrentRegion would do the trick, but it does not work when A1 and the nearby cells are empty. If the only cell with data in the sheet is Q10, then the range should be A1:Q10.
Of course, I could loop over the ws.Cells range to discover the range of interest, but that's quite time consuming, I hope there's more effective way. If I select all cells in a sheet and do a copy-paste to notepad, I do not end up with hundreds of empty columns and thousands of empty rows, only the relevant data are copied. The question is how to replicate that with VBA.
This is my code so far:
Sub CreateTxt()
'This macro copies the contents from all sheets in one text file
'Each sheet contents are prefixed by the sheet name in square brackets
Dim pth As String
Dim fs As Object
Dim rng As Range
pth = ThisWorkbook.Path
Set fs = CreateObject("Scripting.FileSystemObject")
Dim outputFile As Object
Set outputFile = fs.CreateTextFile(pth & "\Output.txt", True)
Dim WS_Count As Integer
Dim ws As Worksheet
Dim I As Integer
WS_Count = ActiveWorkbook.Worksheets.Count
For I = 1 To WS_Count
Set ws = ActiveWorkbook.Worksheets(I)
outputFile.WriteLine ("[" & ws.Name & "]")
Debug.Print ws.Name
Set rng = ws.Range("A1").CurrentRegion
outputFile.WriteLine (GetTextFromRangeText(rng, vbTab, vbCrLf))
Next I
outputFile.Close
End Sub
Function GetTextFromRangeText(ByVal poRange As Range, colSeparator As String, rowSeparator As String) As String
Dim vRange As Variant
Dim sRow As String
Dim sRet As String
Dim I As Integer
Dim j As Integer
If Not poRange Is Nothing Then
vRange = poRange
Debug.Print TypeName(vRange)
For I = LBound(vRange) To UBound(vRange)
sRow = ""
For j = LBound(vRange, 2) To UBound(vRange, 2)
If j > LBound(vRange, 2) Then
sRow = sRow & colSeparator
End If
sRow = sRow & vRange(I, j)
Next j
If sRet <> "" Then
sRet = sRet & rowSeparator
End If
sRet = sRet & sRow
Next I
End If
GetTextFromRangeText = sRet
End Function
if there is anything in A1:B2 cells, this macro works. It breaks when the A1:B2 is empty and the CurrentRegion property returns Empty.
I think you should use these functions to find the last Row/Column
lastRow = Sheets("Sheetname").Cells(Rows.Count, 1).End(xlUp).Row
lastCol = Sheets("Sheetname").Cells(1, Columns.Count).End(xlToLeft).Column
You specify the name of the sheet and the row/columb-number that you want to find the last cell with information, and it return the number of it.
(In the example the last row in first column, and last column in first row are find)
lastCol will give you an Long as an asnwer. If you want to convert this number into the column letter you can use the next function
Function Col_Letter(lngCol As Long) As String
Dim vArr
vArr = Split(Cells(1, lngCol).Address(True, False), "$")
Col_Letter = vArr(0)
End Function
I hope you find this useful
Thanks to user Rosetta, I've come up with this expression for the sought range:
ws.Range("A1:" & ws.Cells.SpecialCells(xlLastCell).Address)

Range of cells into single cell with carriage return

I am working through my first VBA book and would appreciate if someone would point me in the right direction. How would I transfer a range of rows into a single cell with carriage returns? I would then like to repeat this action for all ranges in the column.
I think I need to:
find the first cell with a value in the column
verify that the next row is not empty
find the last cell in the range
perform "the operation" on the range
Following up on my comments. here is a very simple way to achieve what you want.
Option Explicit
'~~> You can use any delimiter that you want
Const Delim = vbNewLine
Sub Sample()
Dim rngInput As Range, rngOutput As Range
Application.ScreenUpdating = False
Set rngInput = Range("A1:A5") '<~~ Input Range
Set rngOutput = Range("B1") '<~~ Output Range
Concatenate rngInput, rngOutput
Application.ScreenUpdating = True
End Sub
Sub Concatenate(rng1 As Range, rng2 As Range)
Dim cl As Range
Dim strOutPut As String
For Each cl In rng1
If strOutPut = "" Then
strOutPut = cl.Value
Else
strOutPut = strOutPut & Delim & cl.Value
End If
Next
rng2.Value = strOutPut
End Sub
Within the context of a worksheet-level code, the following will work. Column 2 is hard-coded, so you might want to pass in a value or otherwise modify it to fit your needs.
Dim rng As Range
Set rng = Me.Columns(2)
Dim row As Integer
row = 1
' Find first row with non-empty cell; bail out if first 100 rows empty
If IsEmpty(Me.Cells(1, 2)) Then
Do
row = row + 1
Loop Until IsEmpty(Me.Cells(row, 2)) = False Or row = 101
End If
If row = 101 Then Exit Sub
' We'll need to know the top row of the range later, so hold the value
Dim firstRow As Integer
firstRow = row
' Combine the text from each subsequent row until an empty cell is encountered
Dim result As String
Do
If result <> "" Then result = result & vbNewLine
result = result & Me.Cells(row, 2).Text
row = row + 1
Loop Until IsEmpty(Me.Cells(row, 2))
' Clear the content of the range
Set rng = Me.Range(Me.Cells(firstRow, 2), Me.Cells(row, 2))
rng.Clear
' Set the text in the first cell
Me.Cells(firstRow, 2).Value2 = result

Resources