Using Cells inside of Range isn't working? [duplicate] - vba

This question already has answers here:
Excel VBA, getting range from an inactive sheet
(3 answers)
Closed 5 years ago.
For some reason this isn't working:
.Range(Cells(1, 1), Cells(lRows, lCols)).Copy
Any ideas? It's on line 78
Option Explicit
Public Sub averageScoreRelay()
' 1. Run from PPT and open an Excel file
' 2. Start at slide 1 and find a box that contains the words "iq_", if it has those words then it will have numbers after it like so "iq_43" or "iq_43, iq_56, iq_72".
' 3. find those words and numbers in the opened Excel file. Needs to recognize that ", " means there is another entry.
' 3. Copy column containing words from ppt ie. "iq_43"
' 4. Paste a Table into ppt with those values
' 5. Do this for every slide
'Create variables
Dim xlApp As Excel.Application
Dim xlWB As Excel.Workbook
Dim pptSlide As Slide
Dim Shpe As Shape
Dim pptText As String
Dim pptPres As Object
Dim iq_Array As Variant
Dim arrayLoop As Integer
Dim i As Integer
Dim myShape As Object
Dim colNumb As Integer
Dim size As Integer
Dim k As Integer
Dim vsblSld As Object
Dim lRows As Long
Dim lCols As Long
colNumb = 5 'Set #of columns in the workbook
' Create new excel instance and open relevant workbook
Set xlApp = New Excel.Application
'xlApp.Visible = True 'Make Excel visible
Set xlWB = xlApp.Workbooks.Open("C:\Users\pinlop\Desktop\Gate\Macro\averageScores\pptxlpratice\dummyavgscore.xlsx", True, False) 'Open relevant workbook
If xlWB Is Nothing Then ' may not need this if statement. check later.
MsgBox ("Error retrieving Average Score Report, Check file path")
Exit Sub
End If
xlWB.Worksheets.Add After:=xlWB.ActiveSheet
'Make pptPres the ppt active
Set pptPres = PowerPoint.ActivePresentation
'Loop through each pptSlide and check for IQ text box, grab avgScore values and create pptTable
For Each pptSlide In pptPres.Slides
'searches through shapes in the slide
For Each Shpe In pptSlide.Shapes
'Identify if there is text frame
k = 1
If Shpe.HasTextFrame Then
'Identify if there's text in text frame
If Shpe.TextFrame.HasText Then
pptText = Shpe.TextFrame.TextRange
If InStr(1, pptText, "iq_") > 0 Then 'Identify if within text there is "iq_" All IQ's have to be formatted like this "iq_42, iq_43" for now
iq_Array = Split(pptText, ", ") 'set iq_Array as an array of the split iq's
size = UBound(iq_Array) - LBound(iq_Array)
For arrayLoop = 0 To size 'loop for each iq_array
For i = 1 To colNumb 'loops for checking each column
If i = 1 And arrayLoop = 0 Then 'Copies the first column for every slide
xlWB.Worksheets("Sheet1").Columns(1).Copy 'copy column
xlWB.Worksheets("Sheet2").Paste Destination:=xlWB.Worksheets("Sheet2").Columns(1)
ElseIf xlWB.Worksheets("Sheet1").Cells(1, i) = iq_Array(arrayLoop) And i <> 1 Then 'if iq in ppt = iq in xl and if not the first cell then execute
k = k + 1
xlWB.Worksheets("Sheet1").Columns(i).Copy
xlWB.Worksheets("Sheet2").Paste Destination:=xlWB.Worksheets("Sheet2").Columns(k)
End If
Next i
Next arrayLoop
End If
End If
End If
Next Shpe
'calculate last row and last column
With xlWB.Worksheets("Sheet2")
lRows = .Cells(.Rows.Count, 1).End(xlUp).Row
lCols = .Cells(1, .Columns.Count).End(xlToLeft).Column
.Range(Cells(1, 1), Cells(lRows, lCols)).Copy
End With
pptSlide.Shapes.PasteSpecial DataType:=ppPasteHTML, Link:=msoFalse
Set myShape = pptSlide.Shapes(pptSlide.Shapes.Count)
'Set position:
myShape.Left = 66
myShape.Top = 152
xlWB.Worksheets("Sheet2").Range("A1:P10").Clear
Next pptSlide
xlWB.Worksheets("Sheet2").Delete
End Sub

It should be like this:
.Range(.Cells(1, 1), .Cells(lRows, lCols)).Copy
That's one of the errors everyone experiences with VBA, if he goes a bit deeper. The reason is that Cells and Range should both be referred to the worksheet, otherwise they would refer the ActiveSheet.
And in general, consider using Long instead of Integer in your code.

Related

Powerpoint VBA copy text from tables

I am trying to create a macro which copies the text from all the tables in a slide. I can select the tables but failed to copy text entries from tables. I need to paste the copied text to a excel spreadsheet.
Here is the script:
Option Explicit
Sub GetTableNames()
Dim pptpres As Presentation
Set pptpres = ActivePresentation
Dim pptSlide As Slide
Set pptSlide = Application.ActiveWindow.View.Slide
Dim pptShapes As Shape
Dim pptTable As Table
For Each pptSlide In pptpres.Slides
For Each pptShapes In pptSlide.Shapes
If pptShapes.HasTable Then
Set pptTable = pptShapes.Table
pptShapes.Select msoFalse
pptShapes.TextFrame.TextRange.Copy
End If
Next
Next
End Sub
enter image description here
enter image description here
Try this code:
Sub GetTableNames()
Dim pptpres As Presentation
Set pptpres = ActivePresentation
Dim pptSlide As Slide
Set pptSlide = Application.ActiveWindow.View.Slide
Dim pptShapes As Shape, pptTable As Table
Dim XL As Object, WS As Object
Dim arr As Variant, nextTablePlace As Integer, cnt As Integer
Set XL = CreateObject("Excel.Application")
With XL.Workbooks.Add
Set WS = .Worksheets(1)
End With
nextTablePlace = 1 ' to output first table content into Worksheet
For Each pptSlide In pptpres.Slides
For Each pptShapes In pptSlide.Shapes
If pptShapes.HasTable Then
cnt = cnt + 1
Set pptTable = pptShapes.Table
WS.Cells(nextTablePlace, 1) = "Table #: " & cnt ' caption for each table
nextTablePlace = nextTablePlace + 1
ReDim arr(1 To pptTable.Rows.Count, 1 To pptTable.Columns.Count) ' resize array to table dimensions
For rr = 1 To pptTable.Rows.Count
For cc = 1 To pptTable.Columns.Count
arr(rr, cc) = pptTable.Cell(rr, cc).Shape.TextFrame.TextRange.Text 'get text from each cell into array
Next
Next
' flush the arr to Worksheet
WS.Cells(nextTablePlace, 1).Resize(pptTable.Rows.Count, pptTable.Columns.Count) = arr
' to next place with gap
nextTablePlace = nextTablePlace + pptTable.Rows.Count + 2
End If
Next
Next
XL.Visible = True
End Sub

Run-time error 91 on arrays

I'm getting Run-time error 91 on several variable, and I really have no idea what I'm doing wrong...
The variables are: IQRngRef, tempRng, unionVariable
I assume it has something with them all being arrays with the exception of unionVariable (at least it shouldn't be).
Could I get some help here please?
Option Explicit
Private Sub averageScoreRelay()
' 1. Run from PPT and open an Excel file
' 2. Start at slide 1 and find a box that contains the words "iq_", if it has those words then it will have numbers after it like so "iq_43" or "iq_43, iq_56,iq_72".
' 3. find those words and numbers in the opened Excel file after splitting and re-formating string.
' 3. Copy column into a new sheets and repeat for all "iq_'s" until sheets 2 has a table.
' 4. Copy table from xl Paste Table into ppt
' 5. Do this for every slide
'Timer start
Dim StartTime As Double
Dim SecondsElapsed As Double
StartTime = Timer
'Create variables
Dim xlApp As Excel.Application
Dim xlWB As Excel.Workbook
Dim ShRef As Excel.Worksheet
Dim pptPres As Object
Dim colNumb As Long
Dim rowNumb As Long
' Create new excel instance and open relevant workbook
Set xlApp = New Excel.Application
'xlApp.Visible = True 'Make Excel visible
Set xlWB = xlApp.Workbooks.Open("C:\Users\Pinlop\Desktop\Gate\Macros\averageScores\pptxlpratice\dummy2.xlsx", True, False, , , , True, Notify:=False) 'Open relevant workbook
If xlWB Is Nothing Then ' may not need this if statement. check later.
MsgBox ("Error retrieving Average Score Report, Check file path")
Exit Sub
End If
xlApp.DisplayAlerts = False
'Find # of iq's in workbook
Set ShRef = xlWB.Worksheets("Sheet1")
colNumb = ShRef.Cells(1, ShRef.Columns.Count).End(xlToLeft).Column
rowNumb = ShRef.Cells(ShRef.Rows.Count, 1).End(xlUp).Row
Dim IQRef() As String
Dim iCol As Long
Dim IQRngRef() As Range
ReDim IQRef(colNumb)
ReDim IQRngRef(colNumb)
' capture IQ refs locally
For iCol = 2 To colNumb
IQRngRef(iCol) = ShRef.Range(ShRef.Cells(1, iCol), ShRef.Cells(rowNumb, iCol)).Value
IQRef(iCol) = ShRef.Cells(1, iCol).Value
Next iCol
'Make pptPres the ppt active
Set pptPres = PowerPoint.ActivePresentation
'Create variables for the slide loop
Dim pptSlide As Slide
Dim Shpe As Shape
Dim pptText As String
Dim iq_Array As Variant
Dim arrayLoop As Long
Dim myShape As Object
Dim outCol As Long
Dim i As Long
Dim lRows As Long
Dim lCols As Long
Dim k As Long
'Loop through each pptSlide and check for IQ text box, grab avgScore values and create pptTable
For Each pptSlide In pptPres.Slides
i = 0
pptSlide.Select
'searches through shapes in the slide
For Each Shpe In pptSlide.Shapes
If Not Shpe.HasTextFrame Then GoTo nextShpe 'boom, one less nested If statement
If Not Shpe.TextFrame.HasText Then GoTo nextShpe ' boom, another nested If statement bites the dust
outCol = 0
'Set pptText as the Text in the box, then make it lowercase and trim Spaces and Enters
pptText = Shpe.TextFrame.TextRange
pptText = LCase(Replace(pptText, " ", vbNullString))
pptText = Replace(Replace(Replace(pptText, vbCrLf, vbNullString), vbCr, vbNullString), vbLf, vbNullString)
'Identify if within text there is "iq_"
If InStr(1, pptText, "iq_") <= 0 Then GoTo nextShpe
'set iq_Array as an array of the split iq's
iq_Array = Split(pptText, ",")
Dim hasIQs As Boolean
Dim checkStr As String
Dim pCol As Long
Dim checkOne
checkOne = iq_Array(0)
hasIQs = Left(checkOne, 3) = "iq_"
Dim tempRng() As Range
If hasIQs Then
' paste inital column into temporary worksheet
tempRng(0) = ShRef.Columns(1)
End If
' loop for each iq_ in the array
For arrayLoop = LBound(iq_Array) To UBound(iq_Array)
' Take copy of potential ref and adjust to standard if required
checkStr = iq_Array(arrayLoop)
If hasIQs And Left(checkStr, 3) <> "iq_" Then checkStr = "iq_" & checkStr
' Look for existence of corresponding column in local copy array
pCol = 0
For iCol = 2 To colNumb
If checkStr = IQRef(iCol) Then
pCol = iCol
Exit For
End If
Next iCol
If pCol > 0 Then
' Paste the corresponding column into the forming table
outCol = outCol + 1
tempRng(outCol) = ShRef.Columns(pCol)
End If
Next arrayLoop
If outCol > 1 Then 'data was added
' Copy table
Dim unionVariable As Range
unionVariable = tempRng(0)
For k = 1 To i
unionVariable = Union(unionVariable, tempRng(k))
Next k
unionVariable.Copy ' all the data added to ShWork
tryAgain:
ActiveWindow.ViewType = ppViewNormal
ActiveWindow.Panes(2).Activate
Set myShape = pptSlide.Shapes.PasteSpecial(DataType:=ppPasteHTML, Link:=msoFalse)
On Error GoTo tryAgain
On Error GoTo clrSht
'Set position:
myShape.Left = -200
myShape.Top = 150 + i
i = i + 150
End If
clrSht:
'Clear Sheet2 for next slide
Erase tempRng()
nextShpe:
Next Shpe
nextSlide:
Next pptSlide
xlWB.Close
xlApp.Quit
xlApp.DisplayAlerts = True
'End Timer
SecondsElapsed = Round(Timer - StartTime, 2)
MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation
End Sub
Dim something() As String
That's declaring a dynamically-sized array, where each item is a String. Once it's resized, you can do this (assuming i is within the boundaries of the array):
something(i) = "foo"
Now this:
Dim something() As Range
That's declaring a dynamically-sized array, where each item is a Range. Once it's resized, you can do this (assuming i is within the boundaries of the array):
Set something(i) = Range("A1")
Notice the Set keyword - it's required in VBA, whenever you're assigning an object reference. Range being an object, you need the Set keyword for that assignment.
In your code:
tempRng(0) = ShRef.Columns(1)
That's indeed a Range, but the Set keyword is missing. That will throw the RTE91 you're getting.
Same here:
unionVariable = tempRng(0)
You can't assign an object reference without the Set keyword.
Here though:
IQRngRef(iCol) = ShRef.Range(ShRef.Cells(1, iCol), ShRef.Cells(rowNumb, iCol)).Value
That's not a Range. It's the .Value of a Range, and that's a Variant - not an object, so adding the Set keyword isn't going to fix anything. If you mean IQRngRef to hold Range objects, you need to do this:
Set IQRngRef(iCol) = ShRef.Range(ShRef.Cells(1, iCol), ShRef.Cells(rowNumb, iCol))

Copy from Excel Worksheets to specific Powerpoint slides

I am transferring data from excel to powerpoint slides with an automated script by using EXcel VBA. I'm trying to copy the usedrange of a excel worksheet and paste it to as a image in a powerpoint Template of 4th slide and from there on it should add new slides and copy the remaining worksheets to the next further slides.
So, In my code for the first iteration it is copying from excel worksheet of first sheet and pasting it in the 4th slide but for the next iteration it is throwing the error as below:
The code which i'm currently using is getting the following error
"Run Time Error -2147188160(80048240) AutomationError".
I'm new to Excel VBA. Please help
Can anyone suggest me the code for the following.
Hope this is clearly explained. If not please ask for more clarification.
Thanks
Private Sub CommandButton2_Click()
Dim PP As PowerPoint.Application
Dim PPpres As Object
Dim PPslide As Object
Dim PpTextbox As PowerPoint.Shape
Dim SlideTitle As String
Dim SlideNum As Integer
Dim WSrow As Long
Dim Sh As Shape
Dim Rng As Range
Dim myshape As Object
Dim myobject As Object
'Open PowerPoint and create new presentation
Set PP = GetObject(class, "PowerPoint.Application")
PP.Visible = True
Set PPpres = PP.Presentations.Open("\\C:\Users\Templates")
'Specify the chart to copy and copy it
For Each WS In Worksheets
If (WS.Name) <> "EOS" Then
ThisWorkbook.Worksheets(WS.Name).Activate
ThisWorkbook.ActiveSheet.UsedRange.CopyPicture
lastrow = ActiveSheet.UsedRange.Rows(ActiveSheet.UsedRange.Rows.Count).Row
'Copy Range from Excel
Set Rng = ThisWorkbook.ActiveSheet.Range("A1:I" & lastrow)
'Copy Excel Range
Rng.Copy
For k = 4 To 40
slidecount = PPpres.Slides.Count
PP.ActiveWindow.View.GotoSlide (k)
'Paste to PowerPoint and position
Set PPslide = PPpres.Slides(k)
PPslide.Shapes.PasteSpecial DataType:=10 '2 = ppPasteEnhancedMetafile
Set myshape = PPslide.Shapes(PPslide.Shapes.Count)
'Set position:
myshape.Left = 38
myshape.Top = 152
'Add the title to the slide
SlideTitle = "Out of Support, " & WS.Name & " "
Set PpTextbox = PPslide.Shapes.AddTextbox(msoTextOrientationHorizontal,
0, 20, PPpres.PageSetup.SlideWidth, 60)
PPslide.Shapes(1).TextFrame.TextRange = SlideTitle
'Set PPslide = PPpres.Slides.Add(slidecount + 1, ppLayoutTitle)
'Make PowerPoint Visible and Active
PP.Visible = True
PP.Activate
'Clear The Clipboard
Application.CutCopyMode = False
Next k
Exit For
End If
Next WS
End Sub

Copy tables from different worksheet in excel and paste it in existing presentation

I have a specific excel workbook which has tables in different worksheets in different range.I want tables should be automatically copied from all the worksheet of my excel workbook and should be pasted in different slides of my existing ppt template.
I have created a code but giving error on range which I want to copy:
Sub newpp()
Dim pptapp As PowerPoint.Application
Dim pres As PowerPoint.Presentation
Dim preslide As PowerPoint.Slide
Dim shapepp As PowerPoint.Shape
Dim exappli As Excel.Application
Dim exworkb As Workbook
Dim xlwksht As Worksheet
Dim rng As Range
Dim myshape As Object
Dim mychart As ChartObject
Dim lastrow1 As Long
Dim lastcolumn1 As Long
Dim slidecount As Long
'Open powerpoint application
Set exappli = New Excel.Application
exappli.Visible = True
'activate powerpoint application
Set pptapp = New PowerPoint.Application
pptapp.Visible = True
pptapp.Activate
'open the excel you wish to use
Set exworkb = exappli.Workbooks.Open("C:\Users\ap\Desktop\Macro\Reference Sheet.xlsm")
'open the presentation you wish to use
Set pres = pptapp.Presentations.Open("C:\Users\ap\Desktop\Macro\new template.pptx")
'Add title to the first slide
With pres.Slides(1)
If Not .Shapes.HasTitle Then
Set shapepp = .Shapes.AddTitle
Else: Set shapepp = .Shapes.Title
End If
With shapepp
.TextFrame.TextRange.Text = "Gulf+ Market Segment Analysis Report" & vbNewLine & "P5 Week 04 FY17"
.TextFrame.TextRange.Font.Name = "Arial Black"
.TextFrame.TextRange.Font.Size = 24
.TextEffect.FontBold = msoTrue
.TextFrame.TextRange.Paragraphs.ParagraphFormat.Alignment = ppAlignLeft
End With
End With
'set the range
lastrow1 = exworkb.ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row
lastcolumn1 = exworkb.ActiveSheet.Cells(1, Columns.Count).End(xlToLeft).Column
For Each xlwksht In exworkb.Worksheets
xlwksht.Select Application.Wait(Now + TimeValue("0.00:1"))
**'getting error in this line-------**
exworkb.ActiveSheet.Range(Cells(1, 1), Cells(lastrow1, lastcolumn1)).CopyPicture appearance:=xlScreen, Format:=xlPicture
slidecount = pres.Slides.Count
Set preslide = pres.Slides.Add(slidecount + 1, 12)
preslide.Select
preslide.Shapes.Paste.Select
pptapp.ActiveWindow.Selection.ShapeRange.Align msoAlignTops, msoTrue
pptapp.ActiveWindow.Selection.ShapeRange.Top = 65
pptapp.ActiveWindow.Selection.ShapeRange.Left = 72
pptapp.ActiveWindow.Selection.ShapeRange.Width = 700
Next xlwksht
End Sub
Replace your For Each xlwksht In exworkb.Worksheets loop with the modified loop below.
I made the following modifications to your code (so it will work):
Instead of Selecting the worksheet and then use ActiveSheet, use xlwksht, I've added the With xlwksht.
You need to search for the last row and column for each worksheet, so I've moved it inside the With statement.
There is no need to Select the slide every time in order to paste.
Some other modifications...
Modified For loop Code
For Each xlwksht In exworkb.Worksheets
With xlwksht
lastrow1 = .Cells(.Rows.Count, "A").End(xlUp).Row
lastcolumn1 = .Cells(1, .Columns.Count).End(xlToLeft).Column
' set the range
.Range(.Cells(1, 1), .Cells(lastrow1, lastcolumn1)).CopyPicture appearance:=xlScreen, Format:=xlPicture
Set preslide = pres.Slides.Add(pres.Slides.Count + 1, 12) ' <-- set the Slide
preslide.Shapes.Paste
With preslide.Shapes(preslide.Shapes.Count) '<-- modify the pasted shape properties
.Top = 65
.Left = 72
' etc...
End With
End With
Next xlwksht

Copy Worksheets break links

I have the below 2 subs in VBA which perform 2 different but similar tasks. One allows you to selects sheets from a Workbook using a checkbox popup and then copies these sheets into a new blank Workbook. The other allows you to manually populate a list of names of the sheets you want to copy (i.e. setup a "batch" of sorts) on a sheet and then copy all the sheets across into a new blank Workbook in a similar fashion to the first.
The problem I am having is - with the first sub I am able to break links after copying into the new Workbook, but with the second sub I am not able to break links. I think it has to do with a number of defined names within the original Workbook, as if you "Move or Copy/Create a Copy" manually, you are able to break the links.
Is there any code I can add to the below (onto both subs if possible) which will automatically break all links in the new Workbook to the old one? Or at least, is it possible to amend the second sub so that it copies across in a similar fashion to the first one which will then allow me to break links manually?
Sub CopySelectedSheets()
'1. Declare variables
Dim I As Integer
Dim SheetCount As Integer
Dim TopPos As Integer
Dim lngCheckBoxes As Long, y As Long
Dim intTopPos As Integer, intSheetCount As Integer
Dim intHor As Integer
Dim intWidth As Integer
Dim intLBLeft As Integer, intLBTop As Integer, intLBHeight As Integer
Dim Printdlg As DialogSheet
Dim CurrentSheet As Worksheet, wsStartSheet As Worksheet
Dim CB As CheckBox
Dim firstSelected As Boolean
' Dim wb As Workbook
' Dim wbNew As Workbook
' Set wb = ThisWorkbook
' Workbooks.Add ' Open a new workbook
' Set wbNew = ActiveWorkbook
On Error Resume Next
Application.ScreenUpdating = False
'2. Check for protected workbook
If ActiveWorkbook.ProtectStructure Then
MsgBox "Workbook is protected.", vbCritical
Exit Sub
End If
'3. Add a temporary dialog sheet
Set CurrentSheet = ActiveSheet
Set wsStartSheet = ActiveSheet
Set Printdlg = ActiveWorkbook.DialogSheets.Add
SheetCount = 0
'4. Add the checkboxes
TopPos = 40
For I = 1 To ActiveWorkbook.Worksheets.Count
Set CurrentSheet = ActiveWorkbook.Worksheets(I)
'Skip empty sheets and hidden sheets
If Application.CountA(CurrentSheet.Cells) <> 0 And _
CurrentSheet.Visible Then
SheetCount = SheetCount + 1
Printdlg.CheckBoxes.Add 78, TopPos, 150, 16.5
Printdlg.CheckBoxes(SheetCount).Text = _
CurrentSheet.Name
TopPos = TopPos + 13
End If
Next I
'6. Move the OK and Cancel buttons
Printdlg.Buttons.Left = 240
'7. Set dialog height, width, and caption
With Printdlg.DialogFrame
.Height = Application.Max _
(68, Printdlg.DialogFrame.Top + TopPos - 34)
.Width = 230
.Caption = "Select sheets to generate"
End With
'Change tab order of OK and Cancel buttons
'so the 1st option button will have the focus
Printdlg.Buttons("Button 2").BringToFront
Printdlg.Buttons("Button 3").BringToFront
'9. Display the dialog box
CurrentSheet.Activate
wsStartSheet.Activate
Application.ScreenUpdating = True
If SheetCount <> 0 Then
If Printdlg.Show Then
For Each CB In Printdlg.CheckBoxes
If CB.Value = xlOn Then
If firstSelected Then
Worksheets(CB.Caption).Select Replace:=False
Else
Worksheets(CB.Caption).Select
firstSelected = True
End If
'For y = 1 To ActiveWorkbook.Worksheets.Count
'If WorksheetFunction.IsNumber _
'(InStr(1, "ActiveWorkbook.Sheets(y)", "Contents")) = True Then
'CB.y = xlOn
'End If
End If
Next
ActiveWindow.SelectedSheets.Copy
Else
MsgBox "No worksheets selected"
End If
End If
' Delete temporary dialog sheet (without a warning)
'' Application.DisplayAlerts = False
'' Printdlg.Delete
' Reactivate original sheet
'' CurrentSheet.Activate
'' wsStartSheet.Activate
'10.Delete temporary dialog sheet (without a warning)
Application.DisplayAlerts = False
Printdlg.Delete
'11.Reactivate original sheet
CurrentSheet.Activate
wsStartSheet.Activate
Application.DisplayAlerts = True
End Sub
Sub CopySpecificSheets()
'1. Declare Variables
Dim myArray() As String
Dim myRange As Range
Dim Cell As Range
Dim OldBook As String
Dim newBook As String
Dim a As Long
'2. Set Range of Lookup
Set myRange = Sheets("Report Batch").Range("A2:A40")
OldBook = ActiveWorkbook.Name
'3. Generate Array of Sheet Names removing Blanks
For Each Cell In myRange
If Not Cell = "" Then
a = a + 1
ReDim Preserve myArray(1 To a)
myArray(a) = Cell
End If
Next
'4. Copy Array of Sheets to new Workbook
For a = 1 To UBound(myArray)
If a = 1 Then
Sheets(myArray(a)).Copy
newBook = ActiveWorkbook.Name
Workbooks(OldBook).Activate
Else
Sheets(myArray(a)).Copy After:=Workbooks(newBook).Sheets(a - 1)
Workbooks(OldBook).Activate
End If
Next
End Sub
Try something like this:
Sub CopySpecificSheets()
'1. Declare Variables
Dim rngData As Range
Dim arrData As Variant
Dim arrSheets() As String
Dim lSheetCount As Long
Dim i As Long
Dim j As Long
'2. Initialize variables
Set rngData = Sheets("Report Batch").Range("A2:A40")
arrData = rngData.Value
lSheetCount = WorksheetFunction.CountA(rngData)
ReDim arrSheets(lSheetCount - 1)
'3. Fill the array with non blank sheet names
For i = LBound(arrData) To UBound(arrData)
If arrData(i, 1) <> vbNullString Then
arrSheets(j) = arrData(i, 1)
j = j + 1
End If
' early break if we have all the sheets
If j = lSheetCount Then
Exit For
End If
Next i
'4. Copy the sheets in one step
Sheets(arrSheets).Copy
End Sub
Thanks
This isn't tested, but I think if you add in a subroutine to your source workbook VBA code like this:
Sub BreakLinks(ByRef wb As Workbook)
Dim Links As Variant
Dim i As Long
On Error Resume Next
Links = wb.LinkSources(Type:=xlLinkTypeExcelLinks)
On Error GoTo 0
If Not IsEmpty(Links) Then
For i = 1 To UBound(Links)
wb.BreakLink Name:=Links(i), _
Type:=xlLinkTypeExcelLinks
Next i
End If
End Sub
And then call it after you copy the sheets to the new workbook
Call BreakLinks(newBook)
That should achieve the desired effect of severing those links. Just be sure the links are broken to any sort of Save or SaveAs operation so that the broken links are maintained.