Applying an Excel formula with macro - vba

Thank you for taking the time to read my query.
I have a problem with applying a formula to one of my Excel sheets. I'm currently using a macro to combine few sheets into one. It's quite rough but it does the job.
Sub Combine()
Application.DisplayAlerts = False
Sheets("Combined").Delete
Application.DisplayAlerts = True
Dim J As Integer
On Error Resume Next
Sheets(1).Select
Worksheets.Add
Sheets(1).Name = "Combined"
Sheets(2).Activate
Range("A1").EntireRow.Select
Selection.Copy Destination:=Sheets(1).Range("A1")
For J = 3 To 6
Sheets(J).Activate
Range("A1").Select
Selection.CurrentRegion.Select
Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Select
Selection.Copy Destination:=Sheets(1).Range("A65536").End(xlUp)(2)
Sheets("Combined").Visible = False
Next
End Sub
This is giving me a specific page from which I need to draw the info. I will tie it to button for easy access in the future. I'm currently struggling with applying a formula that draws info from the aforementioned 'Combined' sheet. The formula that I'm using is lost upon deleting the sheet in the beginning of the code.
=IF(ISNUMBER(SEARCH("_",Combined!A2)),LEFT(Combined!A2,(FIND("_",Combined!A2,1)-1)))
So I tried applying it to a macro. But as you can see there is an underscore in there, that VBA has a very specific interpretation of it. Is there a workaround?
Sub Place_formula()
'trying to place the formulae once again
Range("F2").Formula =
"=IF(ISNUMBER(SEARCH("_",Combined!A2)),LEFT(Combined!A2,
(FIND("_",Combined!A2,1)-1)))"
End Sub
If I manage to do this I will easily find a way to replicate it to where it is needed.

You must double up the quotes in VBA
Range("F2").Formula = "=IF(ISNUMBER(SEARCH(""_"",Combined!A2)),LEFT(Combined!A2,(FIND(""_"",Combined!A2,1)-1)))"
Also suggest amending your main code to avoid the selecting, and using some worksheet variables to make it easier to refer to relevant sheets.
Sub Combine()
Application.DisplayAlerts = False
workSheets("Combined").Delete
Application.DisplayAlerts = True
Dim ws1 As Worksheet, ws2 As Worksheet
Dim J As Long
Set ws1 = Sheets(1)
Set ws2 = Worksheets.Add(before:=ws1)
ws2.Name = "Combined"
ws1.Range("A1").EntireRow.Copy Destination:=ws2.Range("A1")
For J = 3 To 6
With workSheets(J).Range("A1").CurrentRegion
.Offset(1, 0).Resize(.Rows.Count - 1).Copy Destination:=ws2.Range("A" & Rows.Count).End(xlUp)(2)
End With
Next
ws2.visible = False
End Sub

Related

VBA: how to avoid copying table headers from multiple sheets?

Trying to combine multiple excel sheets is there a way to modify the below so that it does not copy table headers from the other sheets into a sheet called "Combined"?
Sub Combine()
'UpdatebyExtendoffice
Dim J As Integer
On Error Resume Next
Sheets(1).Select
Worksheets.Add
Sheets(1).Name = "Combined"
Sheets(2).Activate
Range("A1").EntireRow.Select
Selection.Copy Destination:=Sheets(1).Range("A1")
For J = 2 To Sheets.Count
Sheets(J).Activate
Range("A1").Select
Selection.CurrentRegion.Select
Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Select
Selection.Copy Destination:=Sheets(1).Range("A65536").End(xlUp)(2)
Next
End Sub
Quick rewrite and introducing some variables to hold the new sheet and copy range which should help for debugging.
This also incorporates the "skip two header rows" requirement:
Sub Combine()
Dim J As Integer
'Set the newly added sheet to a variable so we can reference.
Dim CombineSheet as Worksheet
Set CombineSheet = Worksheets.Add
CombineSheet.Name = "Combined"
'Assume you are copying the header here. It's a
' little risky hoping that Sheets(2) is going
' to be the one you want.
'Furthermore, getting rid of select/activate
' stuff. Instead directly say which sheet and
' range you want to copy and its destination.
Sheets(2).Range("A1").EntireRow.Copy Destination:=CombineSheet.Range("A1")
'Introducing a new variable to hold the range that will be copied
Dim copyRange as Range
For J = 2 To Sheets.Count
'Cutting out the activates and selects here
Set copyRange = Sheets(J).Range("A1").CurrentRegion
'Offset it and resize skipping 2 header rows and resizing the whole
' range to be 2 rows smaller (the 2 rows we just skipped)
copyRange = copyRange.Offset(2).Resize(copyRange.Rows.Count - 2)
'Copy/Paste
copyRange.Copy Destination:=CombineSheet.Range("A65536").End(xlUp)
Next
End Sub
The biggest change here, besides the removal of the .Select and .Activate is just offsetting by 2 rows and then resizing that range by -2 rows to accommodate that offset.
Try the next updated code, please:
Sub CombineSheets()
Dim J As Long, sh As Worksheet
Worksheets.Add Before:=Sheets(1)
Sheets(1).Name = "Combined"
Sheets(2).Range("A1").EntireRow.Copy Destination:=Sheets(1).Range("A1")
For Each sh In ActiveWorkbook.Sheets
If sh.Name <> Sheets(1).Name Then
sh.Range("A1").CurrentRegion.Offset(2).Resize(sh.Range("A" & sh.rows.Count).End(xlUp).row - 1).Copy _
Destination:=Sheets(1).Range("A" & sh.rows.Count).End(xlUp)(2)
End If
Next
End Sub
Selecting, activating only consume Excel resources and make the code slower...

Copy and paste rows from one to another worksheet VBA

I know already a few people had that problem but their solutions did not help me. I am pretty new to VBA and I want to copy a row if the respective first cell is not empty to another file and iterate as long as the data is.
So far so good. My code runs the first time and actually works (for one line). But then the macro does not open the file again and spits out an error. If I want to manually open the target file it says: "Removed Feature: Data Validation from /xl/worksheets/sheet2.xml part" (and I think this is the reason why it does not iterate further). Do you have any idea what I can do?
Sub transferData()
Dim LastRow As Long, i As Integer, erow As Long
LastRow = ActiveSheet.Range("BC" & Rows.Count).End(xlUp).Row
For i = 3 To LastRow
If IsEmpty(Cells(i, 63).Value) = False Then
Range(Cells(i, 55), Cells(i, 63)).Select
Selection.Copy
Workbooks.Open Filename:="PATH.xlsx"
Worksheets("NewProjects").Select
erow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
ActiveSheet.Cells(erow, 1).Select
ActiveSheet.PasteSpecial
ActiveSheet.Sort.SortFields.Clear
ActiveWorkbook.Save
ActiveWorkbook.Close SaveChanges:=False
Application.CutCopyMode = False
End If
Next i
End Sub
Data Validation for the file is corrupt (dropdown lists) - either delete Data Validation, or fix it
Once the file is fixed, the code bellow will copy the data without opening the destination file multiple times. It AutoFilters current sheet for empty values in column BK (63), and copies all visible rows, from columns BC to BK, to the end of the new file (starting at first unused cell in column A)
Option Explicit
Public Sub TransferData()
Const OLD_COL1 = "BC"
Const OLD_COL2 = "BK"
Const NEW_COL1 = "A"
Dim oldWb As Workbook, oldWs As Worksheet, oldLR As Long
Dim newWb As Workbook, newWs As Worksheet, newLR As Long
On Error Resume Next 'Expected errors: new file not found, new sheet name not found
Set oldWb = ThisWorkbook
Set oldWs = ActiveSheet 'Or: Set oldWs = oldWb.Worksheets("Sheet2")
oldLR = oldWs.Cells(oldWs.Rows.Count, OLD_COL1).End(xlUp).Row
Application.ScreenUpdating = False
Set newWb = Workbooks.Open(Filename:="PATH.xlsx")
Set newWs = newWb.Worksheets("NewProjects")
If Not newWs Is Nothing Then
newLR = newWs.Cells(oldWs.Rows.Count, NEW_COL1).End(xlUp).Row
With oldWs.Range(oldWs.Cells(2, OLD_COL2), oldWs.Cells(oldLR, OLD_COL2))
.AutoFilter Field:=1, Criteria1:="<>"
If .SpecialCells(xlCellTypeVisible).Cells.Count > 2 Then
oldWs.Range(oldWs.Cells(3, OLD_COL1), oldWs.Cells(oldLR, OLD_COL2)).Copy
newWs.Cells(newLR + 1, NEW_COL1).PasteSpecial
Application.CutCopyMode = False
newWs.Sort.SortFields.Clear
newWb.Close SaveChanges:=True
Else
newWb.Close SaveChanges:=False
End If
.AutoFilter
End With
End If
Application.ScreenUpdating = True
End Sub

Excel Macro working different worksheet

Sub CopyPaste()
'
' CopyPaste Macro
'
' Keyboard Shortcut: Ctrl+Shift+P
'
Range("A2:C5").Select
Selection.Copy
Sheets("A").Select
Range("A2").Select
ActiveSheet.Paste
Sheets("Sheet1").Select
Range("A6:C11").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("B").Select
Range("A2").Select
ActiveSheet.Paste
Sheets("Sheet1").Select
Range("A12:C17").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("C").Select
Range("A2").Select
ActiveSheet.Paste
Sheets("Sheet1").Select
Range("A18:C21").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("D").Select
Range("A2").Select
ActiveSheet.Paste
End Sub
I have trying making a Macro to do a basic task but I can't seem to figure it out, can anyone help please! I'm trying to create a macro that will copy data from one worksheet and place into another worksheet based on specific letter.
For example all "A" item will paste automatically into new worksheet name "A". This I can do with no problem. But, when I want to use the same macro with another row with different no of column is where I have my problem.
I already use recorded macro and then if the row from copy worksheet have been reduced, it will paste wrongly in new worksheet.
Is there any way to solve it?
thanks in advance.
P/S--> the new worksheet will have header in it. so it would be nice if they can paste start from A2 row. Can refer image below for example.
See Example / and see comment on the code
Option Explicit
Public Sub Example()
'Declare your Variables
Dim Sht As Worksheet
Dim rng As Range
Dim List As Collection
Dim varValue As Variant
Dim i As Long
With ThisWorkbook
'Set your Sheet name
Set Sht = ActiveWorkbook.Sheets("Sheet1")
'set your auto-filter, A1
With Sht.Range("A1")
.AutoFilter
End With
'Set your agent Column range # (1) that you want to filter it
Set rng = Range(Sht.AutoFilter.Range.Columns(1).Address)
'Create a new Collection Object
Set List = New Collection
'Fill Collection with Unique Values
On Error Resume Next
For i = 2 To rng.Rows.Count
List.Add rng.Cells(i, 1), CStr(rng.Cells(i, 1))
Next i
'Start looping in through the collection Values
For Each varValue In List
'Filter the Autofilter to macth the current Value
rng.AutoFilter Field:=1, Criteria1:=varValue
'Copy the AutoFiltered Range to new Workbook
Sht.AutoFilter.Range.Copy
Worksheets.Add.Paste
ActiveSheet.Name = Left(varValue, 30)
Next ' Loop back
'Go back to main Sheet and removed filters
Sht.AutoFilter.ShowAllData
Sht.Activate
End With
End Sub
Make sure to have header on your data, see below

Excel With Paste as picture repeating for a column

I have tried some of the codes suggested for similar macros.
I need the information in the cells in column L to be individually pasted as pictures in column M. I don't want to manually do this over and over for each of the hundreds of items.
Here is what it looks like without a loop or a repeat. Just doing the operation twice.
Sub pasteaspicture()
pasteaspicture Macro
Range("L3").Select
Selection.Copy
Range("M3").Select
ActiveSheet.Pictures.Paste.Select
Range("L4").Select
Application.CutCopyMode = False
Selection.Copy
Range("M4").Select
ActiveSheet.Pictures.Paste.Select
End Sub
Thanks.
This code should loop from row 3 to end of column L, if that is not what you want then I can edit it for you.
Application.screenupdating = False
With ActiveSheet
LastRow = .Cells(.Rows.Count, "L").End(xlUp).Row
End With
For i = 3 To LastRow
Range("L" & i).Copy
Range("M" & i).Select
ActiveSheet.Pictures.Paste.Select
Next i
Application.screenupdating = true
This code should work, but it includes a select, which is unwanted in VBA but since I have no clue how to use picture paste I used your code as a template.
Here is a quick (but long) way to do it without loops.
It sets ranges and finds the last row of the Column.
You will find Excel has many ways to skin the same nut. Hope this helps.
Sub CopyPic()
Dim lTopRow As Long
Dim lLeftColumn As Long
Dim lRightColumn As Long
Dim lLastRow As Long
With Sheets("Sheet1")
lTopRow = .Range("L3").Row
lLeftColumn = .Range("L3").Column
lLastRow = .Range("L:L").Find("*", , xlValues, , xlByRows, xlPrevious).Row
lRightColumn = lLeftColumn
Application.Goto .Range(Cells(lTopRow, lLeftColumn), Cells(lLastRow, lRightColumn)), scroll:=False
Selection.Copy
lLeftColumn = .Range("M3").Column
lRightColumn = lLeftColumn
Application.Goto .Range(Cells(lTopRow, lLeftColumn), Cells(lLastRow, lRightColumn)), scroll:=False
.Pictures.Paste.Select
End With
End Sub

copy and paste formulas quickly

I have been trying to write a simple code that copies the value from one cell and paste its formula into all the cells in one column (There are several cells, around 3000). The code works, but it takes around 30 min to run, so it's not ok for me. I also tried to let the value of the formula without "=" and then use the replace command, but it does not work as well. Anyone could help me with that in order to run the macro in 1 min? This is the part of my code that I try to do that:
sub copy_paste
Worksheets("Formatar").Range("H1:L1").Copy
Worksheets("Formatar").Range("H3").PasteSpecial xlValue
Worksheets("Formatar").Range("H3:L3").Copy
Range(Selection, Selection.End(xlDown)).Select
Selection.PasteSpecial xlFormulas
end sub
Tell me if this help you...
Sub copy_paste()
Worksheets("Formatar").Range("H1:L1").Copy 'Copy from row 1
Worksheets("Formatar").Range("H3").PasteSpecial xlPasteValues 'paste the values to row 3
Worksheets("Formatar").Range("H3:L3").Copy 'here you copy that (the values)
Range(Selection, Selection.End(xlDown)).Select 'you select eveything from row3
Selection.PasteSpecial xlPasteValues 'and paste it... but you copy just values from 3!
End Sub
And then you paste it over the first occurrence and you lost data.
Here is my suggest.
Sub copy_paste()
Dim sht As Worksheet
Dim r
Dim H
Dim L
Set sht = Sheets("Formatar") 'store the sheet
sht.Activate 'activate it!
Range("H1:L1").Copy
Range("H3").PasteSpecial xlPasteFormulas 'Paste the formula
Range("H3:L3").Copy 'then copy again
H = Range("H1").Column 'Just to take the number of the columns H and L
L = Range("L1").Column
r = Range("H3").End(xlDown).Row - 1 'Take the number of the last blank row.
Range(Cells(3, H), Cells(r, L)).PasteSpecial xlPasteValues
'Here you paste values, of if you need the
'formula use this: xlPasteFormulas
Application.CutCopyMode = False 'never forget this...
End Sub
Edit
May be this could help...
'Application.Calculation = xlManual
Sub copy_paste()
Dim sht As Worksheet
Dim r
Dim H
Dim L
Set sht = Sheets("Formatar") 'store the sheet
sht.Activate 'activate it!
Range("H1:L1").Copy
Range("H3").PasteSpecial xlPasteFormulas 'Paste the formula
Application.Calculation = xlManual 'Not automatic calculation
Range("H3:L3").Copy 'then copy again
H = Range("H1").Column 'Just to take the number of the columns H and L
L = Range("L1").Column
r = Range("H3").End(xlDown).Row - 1 'Take the number of the last blank row.
Range(Cells(3, H), Cells(r, L)).PasteSpecial xlPasteValues
'Here you paste values, of if you need the
'formula use this: xlPasteFormulas
Application.CutCopyMode = False 'never forget this...
Calculate 'Calculate the whole sheet
Application.Calculation = xlCalculationAutomatic 'return automatic calculation
End Sub