How to only copy values using VBA - vba

I need to copy values only without Formula from sheet to another. The following code does copy but only with Formula. I tried some solutions presented in this site but they give me errors.
For i = 2 To LastRow
'sheet to copy from
With Worksheets("Hoist")
'check column H value before copying
If .Cells(i, 8).Value >= -90 _
And CStr(.Cells(i, 9).Value) <> "Approved" _
And CStr(.Cells(i, 9).Value) <> "" _
And CStr(.Cells(i, 10).Value) = "" Then
'copy row to "display" sheet
.Rows(i).Copy Destination:=Worksheets("display").Range("A" & j)
j = j + 1
End If
End With
Next i

Try changing this line:
.Rows(i).Copy Destination:=Worksheets("display").Range("A" & j)
to this:
.Rows(i).Copy
Worksheets("display").Range("A" & j).PasteSpecial xlPasteValues
This however drops all formatting. To include formatting, you'll need to add another line like:
Worksheets("display").Range("A" & j).PasteSpecial xlPasteFormats

Another option is to enter a working column and use AutoFilter to avoid loops
insert a column in column A
the working column formuka is =AND(I2>-90,AND(J2<>"",J2<>"Approved"),K2="")
filter and copy the TRUE rows
delete working column A
code
Sub Recut()
Dim ws As Worksheet
Dim rng1 As Range
Set ws = Sheets("Hoist")
ws.AutoFilterMode = False
Set rng1 = Range([h2], Cells(Rows.Count, "H").End(xlUp))
ws.Columns(1).Columns.Insert
rng1.Offset(0, -8).FormulaR1C1 = "=AND(RC[8]>-90,AND(RC[9]<>"""",RC[9]<>""Approved""),RC[10]="""")"
With rng1.Offset(-1, -8).Resize(rng1.Rows.Count + 1, 1).EntireRow
.AutoFilter Field:=1, Criteria1:="TRUE"
.Copy Sheets("display").Range("A1")
Sheets("display").Columns("A").Delete
End With
ws.Columns(1).Delete
ws.AutoFilterMode = False
End Sub

Related

Copy specific columns in all rows from sheet 1 to sheet 2 based on condition

I tried using the code below but it display the entire row in the new sheet. Is there a way that i can move only specific columns to the new sheet by modifying the vba macro code below?
Thanks in advance!
Sub CopyExpired()
Dim bottomB As Integer
bottomB = Sheets("sheet1").Range("B" & Rows.Count).End(xlUp).Row
Dim c As Range
For Each c In Sheets("sheet1").Range("B1:B" & bottomB)
If c.Value = "expired" Then
c.EntireRow.Copy Worksheets("sheet2").Range("A" & Rows.Count).End(xlUp).Offset(1)
End If
Next c
End Sub
Try to use an .AutoFilter.
Sub CopyExpired()
With Worksheets("sheet1")
If .AutoFilterMode Then .AutoFilterMode = False
With .Cells(1, "A").CurrentRegion
.AutoFilter field:=2, Criteria1:="expired"
With .Resize(.Rows.Count - 1, 1).Offset(1, 0)
If CBool(Application.Subtotal(103, .Cells)) Then
.SpecialCells(xlCellTypeVisible).Copy _
Destination:=Worksheets("sheet2").Range("A" & Rows.Count).End(xlUp).Offset(1)
End If
End With
End With
If .AutoFilterMode Then .AutoFilterMode = False
End With
End Sub
Replace
c.EntireRow.Copy
with
Range("C" & c.Row & ",E" & c.Row & ",H" & c.Row).Copy
and you can select what columns to use
if I didnt do the syntax 100% right then sorry. Dont have excel near me.
1st: please dont use A1 codes in your macros. Rather use the R1C1 method as follows:
dim sh as worksheet
set sh =activeworkbook.activesheet
sh.cells(1,2) = "Test worked!!"
'this will put the text into row 1 column 2 of your sheet.
2nd: you could copy each cell via a subroutine.
for example:
dim rw1 as integer, lastRw as integer, cellsToRight as integer
lastRw = sh.UsedRange.SpecialCells(xlCellTypeLastCell).Row
for rw1 = 1 to lrw
for col=1 to 10
sh.cells(rw1,col + cellstoright)=sh.cells(rw1,col)
next col
next rw1
or you could just do the colums yourself manualls, eg... array of integer with the values 1,3,4,6,7,8 ... and then loop over the array with your integers as columns, same thing as the above loops.

Excel VBA copying a filtered selection [duplicate]

I have a sheet called Backlog containing rows and columns of data. I need code that will search row by row in the 2nd to last column looking for #N/A. When it finds #N/A it needs to check the last column if it contains a C or not. If it contains a C then the whole row should be appended to a sheet called Logoff. If the last column does not contain a C then the whole row should be appended to a sheet called Denied. The row should be deleted from the original Backlog sheet once moved to either Logoff or Denied. The code I have below is not working. After the first For Statement it goes to End Sub, but there is not any compiling errors.
Private Sub CommandButton2_Click()
Dim IMBacklogSh As Worksheet
Set IMBacklogSh = ThisWorkbook.Worksheets("Backlog")
Dim logoffSh As Worksheet
Set logoffSh = ThisWorkbook.Worksheets("Claims Logged off")
Dim deniedsh As Worksheet
Set deniedsh = ThisWorkbook.Worksheets("Claims Denied")
IMBacklogSh.Select
Dim i As Long
For i = 3 To Cells(Rows.Count, 13).End(xlUp).Row
If Cells(i, 13).Value = "#N/A" Then
If Cells(i, 14).Value = "C" Then
IMBacklogSh.Rows(i).EntireRow.Copy Destination:=logoffSh.Range("A" & logoffsh.Cells(Rows.Count, "A").End(xlUp).Row + 1)
Else
IMBacklogSh.Rows(i).EntireRow.Copy Destination:=deniedsh.Range("A" & deniedsh.Cells(Rows.Count, "A").End(xlUp).Row + 1)
End If
End If
Next i
End Sub
Try it as If Cells(i, 13).Text = "#N/A" Then . #N/A is an error code, not a value; however, the Range.Text property can be examined or the IsError function could be used to examine the cell's contents for any error.
If Cells(i, 13).Text = "#N/A" Then
'Alternate with IsError
'If IsError(Cells(i, 13)) Then
If Cells(i, 14).Value = "C" Then
IMBacklogSh.Rows(i).EntireRow.Copy _
Destination:=logoffSh.Range("A" & logoffsh.Cells(Rows.Count, "A").End(xlUp).Row + 1)
Else
IMBacklogSh.Rows(i).EntireRow.Copy _
Destination:=deniedsh.Range("A" & deniedsh.Cells(Rows.Count, "A").End(xlUp).Row + 1)
End If
End If
However, individual cell examination is not necessary and time consuming. The AutoFilter method can be used to isolate #N/A with C and #N/A with <>C.
Private Sub CommandButton2_Click()
Dim IMBacklogSh As Worksheet, logoffSh As Worksheet, deniedsh As Worksheet
Set IMBacklogSh = ThisWorkbook.Worksheets("Backlog")
Set logoffSh = ThisWorkbook.Worksheets("Claims Logged off")
Set deniedsh = ThisWorkbook.Worksheets("Claims Denied")
With IMBacklogSh
If .AutoFilterMode Then .AutoFilterMode = False
With .Cells(1, 1).CurrentRegion
.AutoFilter field:=13, Criteria1:="#N/A"
.AutoFilter field:=14, Criteria1:="C"
With .Resize(.Rows.Count - 1, Columns.Count).Offset(1, 0)
If CBool(Application.Subtotal(103, .Cells)) Then
.Copy Destination:= _
logoffSh.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)
'optionally delete the originals
.EntireRow.Delete
End If
End With
.AutoFilter field:=14, Criteria1:="<>C"
With .Resize(.Rows.Count - 1, Columns.Count).Offset(1, 0)
If CBool(Application.Subtotal(103, .Cells)) Then
.Copy Destination:= _
deniedsh.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)
'optionally delete the originals
.EntireRow.Delete
End If
End With
End With
If .AutoFilterMode Then .AutoFilterMode = False
End With
End Sub

Excel VBA on combining multiple formulas [duplicate]

Hello everyone,
I have a problem to create VBA excel to duplicate data.
How to combine duplicate rows and sum the values 3 column in excel?
Thank you.
this one uses Remove Duplicates:
Sub dupremove()
Dim ws As Worksheet
Dim lastrow As Long
Set ws = Sheets("Sheet1") ' Change to your sheet
With ws
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("B2:C" & lastrow)
.Offset(, 4).FormulaR1C1 = "=SUMIF(C1,RC1,C[-4])"
.Offset(, 4).Value = .Offset(, 4).Value
End With
With .Range("A1:A" & lastrow)
.Offset(, 4).Value.Value = .Value
End with
.Range("E1:G" & lastrow).RemoveDuplicates 1, xlYes
End With
End Sub
edited after OP's clarifications
try this
solution maintaining original data:
Option Explicit
Sub main()
With Worksheets("Sheet01") '<== change "Sheet01" as per your actual sheet name
With .Range("A1:C1").Resize(.Cells(.rows.Count, 1).End(xlUp).Row)
.Copy
With .Offset(, .Columns.Count + 1)
.PasteSpecial xlPasteAll ' copy value and formats
.Columns(2).Offset(1).Resize(.rows.Count - 1, 2).FormulaR1C1 = "=SUMIF(C1,RC1,C[-" & .Columns.Count + 1 & "])"
.Value = .Value
.RemoveDuplicates 1, xlYes
End With
End With
End With
End Sub
solution overwriting original data (kept for reference):
Sub main()
Dim helperRng As Range, dataRng As Range
Dim colToFilter As String
Dim colsToSumUp As Long
With Worksheets("Sheet01") '<== change "Sheet01" as per your actual sheet name
Set dataRng = .Range("A2:C2").Resize(.Cells(.rows.Count, 1).End(xlUp).Row - 1)
colToFilter = "A" ' set here the column header you want to sum up on
colsToSumUp = 3 ' number of adjacent columns to sum up with
Set helperRng = dataRng.Offset(, .UsedRange.Columns.Count + 1).Resize(, 1) 'localize "helper" cells first column out of sheet used range
With helperRng
.FormulaR1C1 = "=RC" & Cells(1, colToFilter).Column 'make a copy of the values you want to sum up on
.Offset(, 1).FormulaR1C1 = "=if(countif(R1C[-1]:RC[-1], RC[-1])=1,1,"""")" 'localize with "1" first occurrence of each unique value
With .Offset(, 2).Resize(, colsToSumUp)
.FormulaR1C1 = "=sumif(C" & helperRng.Column & ", RC" & helperRng.Column & ",C[" & Cells(1, colToFilter).Column - helperRng.Column - 1 & "])" 'sum up in adjacent columns
.Value = .Value 'get rid of formulas
End With
.Offset(, 1).SpecialCells(xlCellTypeFormulas, xlTextValues).EntireRow.Delete 'delete rows with repeted values you want to sum up on
dataRng.Columns(2).Resize(.rows.Count, colsToSumUp).Value = .Offset(, 2).Resize(.rows.Count, colsToSumUp).Value 'copy summed up values from "helper" cells
helperRng.Resize(, 1 + 1 + colsToSumUp).Clear 'clear "helper" cells
End With
End With
End Sub
it's commented so that you can follow the code and adapt to your actual data "structure"

Selecting certain columns in VBA after searching

I am trying to search for text on a sheet in column c then if found within the same row select column a and copy and paste to sheet two. i have started with this code
Sub Test()
For Each Cell In Sheets("Asset Capture").Range("C35:C3000")
If Cell.Value = "MONITOR" Then
matchRow = Cell.Row
Rows.Range(matchRow & ":" & matchRow).Select
Selection.Copy
Sheets("GRN Status Report").Select
lastRow = ActiveSheet.UsedRange.Rows.Count
If lastRow > 1 Then lastRow = lastRow + 1
ActiveSheet.Range("A" & lastRow).Select
ActiveSheet.Paste
Sheets("Asset Capture").Select
End If
Next
End Sub
but it is selecting the whole row and i can not figure out how to change the code to select data from just the A column?
Try this:
Sub Test()
Dim Cell As Range, rngDest As Range
Set rngDest = Sheets("Grn Status Report").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
For Each Cell In Sheets("Asset Capture").Range("C35:C3000")
If Cell.Value = "MONITOR" Then
Cell.EntireRow.Cells(1).Copy rngDest
Set rngDest = rngDest.Offset(1, 0)
End If
Next
End Sub
Note you don't need to use Select/Activate, and your code will be more robust if you avoid it as much as possible.
See: How to avoid using Select in Excel VBA macros
Hope you looking for this
Sub Test()
increment = Worksheets("GRN Status Report").Range("A" & Rows.Count).End(xlUp).Row
For Each cell In Sheets("Asset Capture").Range("C5:C3000")
If cell.Value = "MONITOR" Then
matchrow = cell.Row
matchcontent = Range("A" & matchrow).Value
Worksheets("GRN Status Report").Cells(increment, 1) = matchcontent
increment = increment + 1
End If
Next
End Sub

How to use column headers to select different ranges of cells to populate data from a filename

This is a separate question stemming from this post: How to use the filename of an excel file to change a column of cells?
I noticed that in the last post's code it was referencing specific cells (J2,K2). However when using the code, I came into an error when the columns changed. So now I am seeking a way to modify the below code to use the names of the header columns to populate the 2nd column instead of referencing specific cells. I think the only line that really needs adjusting is the myRng line, but I will provide all the code I am trying for reference.
In case you don't read the other post, I will describe the issue. I am trying to fill in the 2nd column (name+type) based on the "name" column and the filename. When I was referencing the K or J row in the code, everything was working fine, but when I load a different file and the columns positions have changed, everything gets messed up.
I need to populate the 2nd column (name+type) to be the exactly the same number or rows as the 1st column (name) which is why I am using the Range ("K2:K" & lastCell) formula.
Is there a way to do this?
Current Attempted VBA code:
' Insert Column after name and then rename it name+type
Rows(1).Find("name").Offset(0, 1).EntireColumn.Insert
Rows(1).Find("name").Offset(0, 1).FormulaR1C1 = "name+type"
Dim myRng As Range
Dim lastCell As Long
Dim myOtherRange As Range
Dim column2Range As Range
myOtherRange = Rows(1).Find("name")
column2Range = Rows(1).Find("name+type")
lastCell = Range(myOtherRange).End(xlDown).Row
Set myRng = Range("K2:K" & lastCell)
myOtherRange.FormulaR2C1 = "=LEFT(MID(CELL(""filename""),SEARCH(""["",CELL(""filename""))+1, SEARCH(""]"",CELL(""filename""))-SEARCH(""["",CELL(""filename""))-1),5)&RC[-1]"
myOtherRange.FormulaR2C1.Select
Selection.Copy
myRng.Select
ActiveSheet.Paste
First Draft VBA code:
' Insert Column after name and then rename it name+type
Rows(1).Find("name").Offset(0, 1).EntireColumn.Insert
Rows(1).Find("name").Offset(0, 1).FormulaR1C1 = "name+type"
'Add the contents to the name+type column
Range("K2").Select
ActiveCell.FormulaR1C1 = "=LEFT(MID(CELL(""filename"",RC[-1]),SEARCH(""["",CELL(""filename"",RC[-1]))+1,SEARCH(""]"",CELL(""filename"",RC[-1]))-SEARCH(""["",CELL(""filename"",RC[-1]))-1),5)&RC[-1]"
Range("K2").Select
Selection.Copy
Range("K2:K8294").Select
ActiveSheet.Paste
#Scott or Siddharth Rout probably =) – Jonny 11 hours ago
I would never recommend this :) SO is full of experts who can assist you. Why do you want to limit the help that you can get? ;)
Is this what you are trying?
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long, aCol As Long
Dim aCell As Range
Set ws = Sheets("Sheet1") '<~~ Change this to the relevant sheet name
With ws
Set aCell = .Rows(1).Find("Name")
'~~> Check if the column with "name" is found
If Not aCell Is Nothing Then
aCol = aCell.Column
.Columns(aCol + 1).EntireColumn.Insert
.Cells(1, aCol + 1).Value = "Name+Type"
.Activate
.Rows(1).Select
With ActiveWindow
.SplitColumn = 0
.SplitRow = 1
.FreezePanes = True
End With
'~~> Get lastrow of Col which has "name"
lRow = .Range(Split(.Cells(, aCol).Address, "$")(1) & .Rows.Count).End(xlUp).Row
ThisWorkbook.Save
'~~> Add the formula to all the cells in 1 go.
.Range(Split(.Cells(, aCol + 1).Address, "$")(1) & "2:" & _
Split(.Cells(, aCol + 1).Address, "$")(1) & lRow).Formula = _
"=LEFT(MID(CELL(""filename"",RC[-1]),SEARCH(""["",CELL(""filename"",RC[-1]))+1," & _
"SEARCH(""]"",CELL(""filename"",RC[-1]))-SEARCH(""["",CELL(""filename"",RC[-1]))-1),5)&RC[-1]"
.Columns("A:AK").Columns.AutoFit
Else
MsgBox "Name Column Not Found"
End If
End With
End Sub
After modifying the code provided by Siddharth, this is the final code that worked for me. The save feature needed to also remove a format and the Formula to search and add the filename to the cells did not work without this edit. I also had to change the sheet to the activeSheet, because it was constantly changing. Here is the code:
Sub Naming()
Dim LR As Long, i As Long, lngCol As Long
lngCol = Rows(1).Find("NAME", lookat:=xlWhole).Column 'assumes there will always be a column with "NAME" in row 1
Application.ScreenUpdating = False
LR = Cells(Rows.Count, lngCol).End(xlUp).Row
For i = LR To 1 Step -1
If Len(Cells(i, lngCol).Value) < 4 Then Rows(i).Delete
Next i
Application.ScreenUpdating = True
' Insert Column after NAME and then rename it NAME+TYPE
Dim ws As Worksheet
Dim lRow As Long, aCol As Long
Dim aCell As Range
Set ws = ActiveSheet 'Need to change to the Active sheet
With ws
Set aCell = .Rows(1).Find("NAME")
' Check if the column with "NAME" is found, it is assumed earlier
If Not aCell Is Nothing Then
aCol = aCell.Column
.Columns(aCol + 1).EntireColumn.Insert
.Cells(1, aCol + 1).Value = "NAME+TYPE"
.Activate
' Freeze the Top Row
Rows("1:1").Select
With ActiveWindow
.SplitColumn = 0
.SplitRow = 1
End With
ActiveWindow.FreezePanes = True
' Get lastrow of Col which has "NAME"
lRow = .Range(Split(.Cells(, aCol).Address, "$")(1) & .Rows.Count).End(xlUp).Row
'Save the file and format the filetype
Dim wkb As Workbook
Set wkb = ActiveWorkbook 'change to your workbook reference
wkb.SaveAs Replace(wkb.Name, "#csv.gz", ""), 52 'change "csv.gz" to ".xlsm" if need be
' Add the formula to all the cells in 1 go.
.Range(Split(.Cells(, aCol + 1).Address, "$")(1) & "2:" & _
Split(.Cells(, aCol + 1).Address, "$")(1) & lRow).Formula = _
"=LEFT(MID(CELL(""filename""),SEARCH(""["",CELL(""filename""))+1, SEARCH(""]"",CELL(""filename""))-SEARCH(""["",CELL(""filename""))-1),5)&RC[-1]"
.Columns("A:AK").Columns.AutoFit
Else
MsgBox "NAME Column Not Found"
End If
End With
' Change the Range of the cursor
Range("A1").Select
Application.CutCopyMode = False
End Sub