I am trying to create an Excel VBA function to search values of column A and find same cells in column H, and replace these cells in B2:F6 with values of J2:N4.
My Input File:
Desired Output:
I have tried the following VBA code but it doesn't work. it finds and replace the values of column Replace1 and ignores Replace 2,3,... .
Sub MultiFindNReplace()
'Update 20140722
Dim Rng As Range
Dim InputRng As Range, ReplaceRng As Range
xTitleId = "KutoolsforExcel"
Set InputRng = Application.Selection
Set InputRng = Application.InputBox("Original Range ", xTitleId, InputRng.Address, Type:=8)
Set ReplaceRng = Application.InputBox("Replace Range :", xTitleId, Type:=8)
Application.ScreenUpdating = False
For Each Rng In ReplaceRng.Columns(1).Cells
InputRng.Replace what:=Rng.Value, replacement:=Rng.Offset(0, 1).Value
Next
Application.ScreenUpdating = True
End Sub
Looks like both datasets got same headers so you can benefit from that. If the headers are always the same and same sorting, just copy whole row:
Sub test()
'if headers of both datasets are always the same and sorted the same way, just copy whole row
Dim rngDestiny As Range
Dim rngSource As Range
Dim rngFind As Range
Dim rng As Range
Dim i As Long
Dim RowN As Long
Dim LR As Long
Set rngSource = Range("I2:M4")
Set rngFind = Range("H2:H4")
Set rngDestiny = Range("B2:F6")
LR = Range("A" & Rows.Count).End(xlUp).Row 'last non-blank cell in column f-name
For i = 2 To LR Step 1
With Application.WorksheetFunction
'check if the value of f-name exists in column FIND
If .CountIf(rngFind, Range("A" & i).Value) > 0 Then
'there is a match, get row number and copy
RowN = .Match(Range("A" & i).Value, rngFind, 0)
rngSource.Rows(RowN).Copy rngDestiny.Rows(i - 1) 'minus 1 because our first row of data starts with i=2!!!
End If
End With
Next i
Set rngSource = Nothing
Set rngFind = Nothing
Set rngDestiny = Nothing
End Sub
Related
I am trying to change range of values with another range of values in VBA. I tried following code but i got error: Type missmatch
Sub ChangeOneToGrade()
Dim rng As Range
Set rng = Application.InputBox(Prompt:="Please select a range", Type:=8)
Dim rng2 As Range
Set rng2 = rng
Dim Count As Integer
For Each cell In rng.Rows
If cell.Value = 1 Then
cell.Value = rng2.Offset(0, Count)
End If
Count = Count + 1
Next cell
End Sub
This isn't ideal, but it should get you on the right track. Cells(Row, Column) is used. You can swap Row & Column, see what happens.
Sub ChangeOneToGrade()
Dim rng1 As Range
Set rng1 = Application.InputBox(Prompt:="Please select a range", Type:=8)
Dim rng2 As Range
Set rng2 = Application.InputBox(Prompt:="Select another range", Type:=8)
Dim cnt As Long: cnt = 1
Dim celll As Range 'extra l on purpose
For Each celll In rng1
'Do 1 IF with "And" and you'll get same Type-Mismatch
If IsNumeric(celll.Value) Then
If celll.Value = 1 Then
rng2.Cells(cnt, 1).Value = 1
cnt = cnt + 1
End If
End If
Next
End Sub
I think this is what you are trying to achieve - replace every occurrence of 1 in rng with the corresponding value in rng2. I have added some default data, and default ranges to the InputBoxs.
Dim i As Integer
For i = 1 To 7
Cells(1, i) = Int(Rnd * 2)
Cells(2, i) = i + 1
Next i
Dim rng As Range
Set rng = Application.InputBox(Prompt:="Please select a range", Default:="a1:g1", Type:=8)
Dim rng2 As Range
Set rng2 = Application.InputBox(Prompt:="Please select a range", Default:="a2:g2", Type:=8)
Dim Count As Integer: Count = 1
For Each cell In rng
If cell.Value = 1 Then
cell.Value = rng2.Columns(Count)
End If
Count = Count + 1
Next cell
Your 'Type mismatch' comes from rng.Rows returns a collection of rows, and so cell was iterating through rows and not cells, and so cell.Value had no meaning.
I am working on excel sheet, in a column having multiple dates and other numbers. I trying to select the date only and copy it to next column. I tried to use Find and replace option but its not working, i used the script of KUTOOLS, but its selecting the range of values. So value falls in the same range of two different values, so could not differentiate. How to select the cells only date in Excel.
Sub FindReplace()
'Update 20150423
Dim Rng As Range
Dim WorkRng As Range
On Error Resume Next
xTitleId = "KutoolsforExcel"
Set WorkRng = Application.Selection
Set WorkRng = Application.InputBox("Range", xTitleId, WorkRng.Address, Type:=8)
For Each Rng In WorkRng
If Rng.Value > 500 Then
Rng.Value = 0
End If
Next
End Sub
Below is the excel sheet
You could try:
Option Explicit
Sub test()
Dim LastRow As Long, i As Long
With ThisWorkbook.Worksheets("Sheet1") '<- Refer to the sheet you want
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row '<- Find the last row of column A
For i = 2 To LastRow '<- Loop from row 2 to last row
If IsDate(.Range("A" & i).Value) Then '<- Check if column A row i is date
'Code Here
End If
Next i
End With
End Sub
You can use the IsDate function on cell.Value (not Value2) to filter if the value is in DATE format.
Dim rng As Range
Set rng = Worksheets(1).Range("A2", "A5")
Dim cell As Range
For Each cell In rng.Cells
With cell
If IsDate(cell.Value) Then
Debug.Print cell.Value
End If
End With
Next cell
I have a code that finds and replaces values in one sheet from a list in another sheet. However, I need this code to also highlight the cell, or flag it in some way so that it can be reviewed manually later. Any suggestions?
Here is the code:
Sub ReplaceValues()
Dim FandR As Worksheet
Dim PDH As Worksheet
Dim rng As Range, rngR As Range
Dim i As Long
Dim rngReplacement
Dim c As Range
Dim curVal As String
Set FandR = Sheets("Find and Replace")
Set PDH = ThisWorkbook.Sheets("Paste Data here")
i = PDH.Rows.Count
With PDH
Set rng = .Range("E1", .Range("E" & i).End(xlUp))
End With
With FandR
Set rngR = FandR.Range("H")
End With
For Each c In rngR
curVal = c.Value
c.Interior.Color = vbYellow
With rng
.Replace curVal, c.Offset(0, 1).Value, xlWhole, , True
End With
Next
End Sub
I am trying to write a UDF that will Move or Delete all columns in an array
This part I have.
I also want to Delete or Move all columns not in the array and this part I am stuck on.
This is Case 2 and 4 of the function
Any help on this is appreciated
Thanks
Edit: Updated with answer provided by David G
Function InvertRng(shtName As String, r As Range) As Range
Dim rng As Range
Dim Rng1 As Range, Rng2 As Range
Set Rng1 = GetUsedRange(shtName, 1, True)
For Each rng In Rng1
If Application.Intersect(rng, r) Is Nothing Then
If InvertRng Is Nothing Then
Set InvertRng = rng
Else
Set InvertRng = Application.Union(InvertRng, rng)
End If
End If
Next
End Function
Original Question
Sub MoveOrDelete_n()
MoveOrDelete 2, "Elements", "NewSheet", Array("Id", "Type", "Description")
End Sub
The Function
Function MoveOrDelete(iwhat As Long, SshtName As String, TshtName As String, arrHeaders As Variant) 'Excel VBA to move Columns based on criteria
Dim wsS As Worksheet, wsT As Worksheet
Dim ar As Variant
Dim fn As Range, r As Range
Dim str As String
Dim i As Long
Set wsS = ThisWorkbook.Sheets(SshtName)
Set wsT = ThisWorkbook.Sheets(TshtName)
For i = 0 To UBound(arrHeaders) 'Loop through the Array
Set fn = wsS.Rows("1:1").Find(arrHeaders(i), LookAt:=xlWhole)
str = str & fn.Address & ","
Next i
'Remove the trailing comma from the string
str = Left(str, Len(str) - 1)
Set r = wsS.Range(str).EntireColumn
Select Case iwhat
Case 1
'Delete all columns IN list
r.Delete
Case 2
'Delete all columns NOT in list
invertR.Delete
Case 3
'Move all columns IN List to NEW Sheet
r.Copy wsT.[a1]
Case 4
'Move all columns NOT in List to NEW SheeT
invertR.Copy wsT.[a1]
End Select
End Function
I found this function that invert the selection, maybe is what you need:
Sub InvertSelection()
'Updateby20140314
Dim rng As Range
Dim Rng1 As Range
Dim Rng2 As Range
Dim OutRng As Range
xTitleId = "KutoolsforExcel"
Set Rng1 = Application.Selection
Set Rng1 = Application.InputBox("Range1 :", xTitleId, Rng1.Address, Type:=8)
Set Rng2 = Application.InputBox("Range2", xTitleId, Type:=8)
For Each rng In Rng2
If Application.Intersect(rng, Rng1) Is Nothing Then
If OutRng Is Nothing Then
Set OutRng = rng
Else
Set OutRng = Application.Union(OutRng, rng)
End If
End If
Next
OutRng.Select
End Sub
https://www.extendoffice.com/documents/excel/762-excel-reverse-selections.html
I have this VBA code
Sub DeleteRows()
Dim rng As Range
Dim InputRng As Range
Dim DeleteRng As Range
Dim DeleteStr As String
xTitleId = "Delete"
Set InputRng = Application.Selection
Set InputRng = Application.InputBox("Range :", xTitleId, InputRng.Address, Type:=8)
DeleteStr = Application.InputBox("Delete Text", xTitleId, Type:=2)
For Each rng In InputRng
If rng.Value = DeleteStr Then
If DeleteRng Is Nothing Then
Set DeleteRng = rng
Else
Set DeleteRng = Application.Union(DeleteRng, rng)
End If
End If
Next
DeleteRng.EntireRow.Delete
End Sub
This one deletes all the rows for the word I input. I need it to delete all the others except the word I input.
Thanks in advance!
Your problem is that you allow the user to select a range of more than one column. With If rng.Value <> DeleteStr Then if the search string exist in one cell of a selected row but not in another cell on the same row, that row is marked for deletion.
So, consider each row seperately. If any cell in that row equals the search string, exclude the row from from deletion
Something like this
Sub DeleteRows()
Dim rng As Range, rw As Range
Dim delRow As Boolean
Dim InputRng As Range
Dim DeleteRng As Range
Dim DeleteStr As String
Dim xTitleId As String
xTitleId = "Delete"
Set InputRng = Application.Selection
Set InputRng = Application.InputBox("Range :", xTitleId, InputRng.Address, Type:=8)
DeleteStr = Application.InputBox("Delete Text", xTitleId, Type:=2)
For Each rw In InputRng.Rows
delRow = True
For Each rng In rw.Cells
If rng.Value = DeleteStr Then
delRow = False
Exit For
End If
Next
If delRow Then
If DeleteRng Is Nothing Then
Set DeleteRng = rw.EntireRow
Else
Set DeleteRng = Application.Union(DeleteRng, rw.EntireRow)
End If
End If
Next
If Not DeleteRng Is Nothing Then
DeleteRng.Delete
End If
End Sub
Your code is sub-optimal as it loops through rows.
A quicker version would use COUNTIF to check if your non-delete condition was met by the row, then you could use an AutoFilter to delete the rows where the condition is not found.
So you could do this manually or with VBA.
If you data was in columns B:D this code inserts the working formula in a new column, then deletes the rows where the condition is true.
=COUNTIF(B2:D2,"Your Condition" )>0
code
Sub Quicker()
Dim rng1 As Range
Dim DeleteStr As String
Dim rng2 As Range
Set rng1 = Application.InputBox("Range :", xTitleId, Selection.Address, , , , , 8)
DeleteStr = Application.InputBox("Delete Text", "Delete", , , , , , 2)
With rng1.Columns(1).Offset(0, rng1.Columns.Count)
.EntireColumn.Insert
.FormulaR1C1 = "=COUNTIF(RC[-" & rng1.Columns.Count + 1 & "]:RC[-2],""" & DeleteStr & """ )>0"
.AutoFilter Field:=1, Criteria1:="FALSE"
'preserve header row
.Offset(1, 0).Resize(rng1.Rows.Count - 1, 1).EntireRow.Delete
On Error Resume Next
.EntireColumn.Delete
On Error GoTo 0
End With
End Sub
This should do the job. You had the EntireRow in the wrong place.
Sub DeleteRows()
' 03 Apr 2017
Dim Cell As Range
Dim InputRng As Range
Dim DeleteRng As Range
Dim DeleteStr As String
Dim xTitleId As String
xTitleId = "Delete"
Set InputRng = Application.InputBox("Range :", xTitleId, Selection.Address, Type:=8)
DeleteStr = InputBox("Delete Text", xTitleId)
For Each Cell In InputRng
If StrComp(Cell.Value, DeleteStr, vbTextCompare) Then
If DeleteRng Is Nothing Then
Set DeleteRng = Cell.EntireRow
Else
Set DeleteRng = Application.Union(DeleteRng, Cell.EntireRow)
End If
End If
Next
DeleteRng.Delete
End Sub