Excel VBA - Error Adding Hyperlink to Another Workbook - vba

I have written this code to take data from one workbook, put it into an array, then place the data in an empty row in another workbook. It works until it gets to i=25 in the For loop where it adds the hyperlink. The hyperlink is actually correctly added, and functions properly, but when I step through the line it gives me a "Application-Defined or Object-Define Error" even though the line added the hyperlink correctly.
Any help would be greatly appreciated. I've been stuck on this for a few days, and have tried many adjustments.
Private Sub CopyDataToMatrix()
'This macro copies the data from the process sheet & automatically pastes it into
'the matrix.
Dim wb1 As Workbook
Dim wb2 As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim Data(1 To 26)
Dim EmptyRow As Range
Dim strSearch As String
Dim rngSearch As Range
Dim rowNum As Integer
Set wb1 = ActiveWorkbook
Set wb2 = Workbooks.Open("***ForPrivacy***")
Set ws1 = wb1.Sheets("ProcessData")
Set ws2 = wb2.Sheets("2016")
'Put all of the data into an array:
Data(1) = ws1.Range("B57").Value
Data(2) = ws1.Range("B3").Value
Data(3) = ws1.Range("B4").Value
Data(4) = ws1.Range("B5").Value
Data(5) = ws1.Range("F7").Value
Data(6) = ws1.Range("B6").Value
Data(7) = ws1.Range("B7").Value
Data(8) = ws1.Range("F8").Value
Data(9) = ws1.Range("B8").Value
Data(10) = ws1.Range("B9").Value
Data(11) = ws1.Range("B10").Value
Data(12) = ws1.Range("F9").Value
Data(13) = ws1.Range("F4").Value
Data(14) = ws1.Range("F5").Value
Data(15) = ws1.Range("F6").Value
Data(16) = ws1.Range("G4").Value
Data(17) = ws1.Range("G5").Value
Data(18) = ws1.Range("G6").Value
Data(19) = ws1.Range("H4").Value
Data(20) = ws1.Range("H5").Value
Data(21) = ws1.Range("H6").Value
Data(22) = ws1.Range("I4").Value
Data(23) = ws1.Range("I5").Value
Data(24) = ws1.Range("I5").Value
Data(25) = Left(wb1.Name, 8)
'IM MATRIX:
'Look to see if the row already exists in IM Matrix with the current file name, and if so overwrite it:
strSearch = Left(wb1.Name, 8)
Set rngSearch = ws2.Range("Y:Y")
If Application.CountIf(rngSearch, strSearch) > 0 Then
rowNum = Application.Match(strSearch, rngSearch, 0)
With ws2
Set EmptyRow = .Cells(rowNum, 1)
For i = LBound(Data) To 24
EmptyRow.Offset(0, i - 1).Value = Application.Index(Data, i)
Next i
For i = 25 To 25
EmptyRow.Offset(0, i - 1).Value = ws2.Hyperlinks.Add(EmptyRow.Offset(0, i - 1), wb1.FullName, , "Click to go to IML file.", Data(i))
Next i
End With
'If the file name isn't already in IM Matrix, then enter data in new row:
Else
With ws2
Set EmptyRow = .Cells(.Rows.Count, 1).End(xlUp).Offset(1)
For i = LBound(Data) To 24
EmptyRow.Offset(0, i - 1).Value = Application.Index(Data, i)
Next i
For i = 25 To 25
**''HERE IS WHERE THE CODE BUGS:**
**EmptyRow.Offset(0, i - 1).Value = ws2.Hyperlinks.Add(EmptyRow.Offset(0, i - 1), wb1.FullName, , "Click to go to IML file.", Data(i))**
Next i
End With
End If
'Close & save IM Matrix file:
wb2.Close SaveChanges:=True
End Sub
Here is the solution that worked with the help of #JMichael:
Private Sub CopyDataToMatrix()
'This macro copies the data from the process sheet & automatically pastes it into
'the matrix.
Dim wb1 As Workbook
Dim wb2 As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim Data(1 To 26)
Dim EmptyRow As Range
Dim strSearch As String
Dim rngSearch As Range
Dim rowNum As Integer
Set wb1 = ActiveWorkbook
Set wb2 = Workbooks.Open("***ForPrivacy***")
Set ws1 = wb1.Sheets("ProcessData")
Set ws2 = wb2.Sheets("2016")
'Put all of the data into an array:
Data(1) = ws1.Range("B57").Value
Data(2) = ws1.Range("B3").Value
Data(3) = ws1.Range("B4").Value
Data(4) = ws1.Range("B5").Value
Data(5) = ws1.Range("F7").Value
Data(6) = ws1.Range("B6").Value
Data(7) = ws1.Range("B7").Value
Data(8) = ws1.Range("F8").Value
Data(9) = ws1.Range("B8").Value
Data(10) = ws1.Range("B9").Value
Data(11) = ws1.Range("B10").Value
Data(12) = ws1.Range("F9").Value
Data(13) = ws1.Range("F4").Value
Data(14) = ws1.Range("F5").Value
Data(15) = ws1.Range("F6").Value
Data(16) = ws1.Range("G4").Value
Data(17) = ws1.Range("G5").Value
Data(18) = ws1.Range("G6").Value
Data(19) = ws1.Range("H4").Value
Data(20) = ws1.Range("H5").Value
Data(21) = ws1.Range("H6").Value
Data(22) = ws1.Range("I4").Value
Data(23) = ws1.Range("I5").Value
Data(24) = ws1.Range("I5").Value
Data(25) = Left(wb1.Name, 8)
'IM MATRIX:
'Look to see if the row already exists in IM Matrix with the current file name, and if so overwrite it:
strSearch = Left(wb1.Name, 8)
Set rngSearch = ws2.Range("Y:Y")
If Application.CountIf(rngSearch, strSearch) > 0 Then
rowNum = Application.Match(strSearch, rngSearch, 0)
With ws2
Set EmptyRow = .Cells(rowNum, 1)
For i = LBound(Data) To 24
EmptyRow.Offset(0, i - 1).Value = Application.Index(Data, i)
Next i
ws2.Hyperlinks.Add EmptyRow.Offset(0, 24), wb1.FullName, , "Click to go to IML file.", Data(25)
End With
'If the file name isn't already in IM Matrix, then enter data in new row:
Else
With ws2
Set EmptyRow = .Cells(.Rows.Count, 1).End(xlUp).Offset(1)
For i = LBound(Data) To 24
EmptyRow.Offset(0, i - 1).Value = Application.Index(Data, i)
Next i
ws2.Hyperlinks.Add EmptyRow.Offset(0, 24), wb1.FullName, , "Click to go to IML file.", Data(25)
End With
End If
'Close & save IM Matrix file:
wb2.Close SaveChanges:=True
End Sub

Based on the code that I got when I recorded creating a hyperlink seems like you need to just remove everything before ws2.Hyperlinks.... The hyperlink creation code contains the cell to put the link in, so I think it inherently fills the .Value for the cell.
Make sure to update the code in that covers the case that Application.CountIf(rngSearch, strSearch) > 0 returns as True since it's the trying to do the same thing.
You could also drop the For loop around adding the hyperlink since you're not really looping. You can either just increment i before the hyperlink creation, or just hardcode the values.

Related

VBA Error: Runtime Error: 9 - Subscript out of range when copying a worksheet from another workbook

I am generating a new workbook from a multiple workbooks, i can generate a summary of all the errors found, but when i try to copy the sheets with the error information i got the runtime error 9
These is the line failing
If exists = True Then
ActiveWorkbook.Sheets(sheetName).Copy After:=ThisWorkbook.Sheets(1)
End If
Other thing i havent add is that all the sheets on the multiple files have the same names, so i want to know if there is a way that the sheet when is copy i can add the file name and the sheet name
Sub getViolations()
Path = "C:\Users\omartinr\Desktop\New folder (4)\New folder\"
Filename = Dir(Path & "*.xls")
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
Set TxtRng = ws.Range("A1:N1")
TxtRng.Font.ColorIndex = 2
TxtRng.Interior.ColorIndex = 5
TxtRng.Value = [{"Partition Name","Tag","EM Supply","SH Signal","PK","Sfactor","FiSH","RESCAL","RESCAL","RESCAL","RESCAL","RESCAL","RESCAL","RESCAL"}]
TxtRng.HorizontalAlignment = xlCenter
Dim i As Integer
i = 2
Do While Filename <> ""
Workbooks.Open Filename:=Path & Filename, ReadOnly:=True
Dim wc As Worksheet
Set wc = ActiveWorkbook.Sheets("Violations Summary")
ws.Cells(i, 1).Value = ActiveWorkbook.Sheets("Violations Summary").Range("B1")
ws.Cells(i, 2).Value = ActiveWorkbook.Sheets("Violations Summary").Range("C1")
Dim count As Integer
count = 15
Dim sheetName As String, mySheetNameTest As String
Dim n As Integer
Dim exits As Boolean
For n = 3 To 14
If Not IsEmpty(wc.Cells(n, 2)) Then
If (wc.Cells(n, 2)) = 0 Then
ws.Cells(i, n).Font.ColorIndex = 4
ws.Cells(i, n).Value = wc.Cells(n, 2)
End If
If (wc.Cells(n, 2)) > 0 Then
Select Case wc.Cells(n, 1)
Case "PK"
sheetName = "Peak"
Case "Sfactor"
sheetName = "SF Supply"
Case Else
sheetName = wc.Cells(n, 1)
End Select
exists = sheetExists(sheetName)
If exists = True Then
ActiveWorkbook.Sheets(sheetName).Copy After:=ThisWorkbook.Sheets(1)
End If
ws.Cells(i, count) = wc.Cells(1, n).Value
ws.Cells(i, n).Font.ColorIndex = 3
ws.Cells(i, n).Value = wc.Cells(n, 2)
End If
If (ActiveWorkbook.Sheets("Violations Summary").Cells(n, 2)) < 0 Then
ws.Cells(i, n).Font.ColorIndex = 3
ws.Cells(i, n).Value = wc.Cells(n, 2)
End If
End If
If IsEmpty(wc.Cells(n, 2)) Then
ws.Cells(i, n).Value = ["NA"]
End If
count = count + 1
Next n
Workbooks(Filename).Close
Filename = Dir()
i = i + 1
Loop
End Sub
Function sheetExists(sheetToFind As String) As Boolean
sheetExists = False
For Each Sheet In Worksheets
If sheetToFind = Sheet.Name Then
sheetExists = True
Exit Function
End If
Next Sheet
End Function
Put option explicit at top so spelling of variables is checked and that they are declared. The variable exists was mispelt and there were a number of other variables not declared. I have put some other comments in with the code.
Some of the logic i think can be simplified and i have given some examples. Also, ensure consistent use of named variable wc. If nothing else it should be easier to debug now. Compiles on my machine so give it a try.
This all works on the assumption that each workbook you open has the "Violations Summary" sheet and it is spelt as shown.
You have the filename already stored in the variable Filename so you can use (concatenate?) that with the sheetname variable.
Option Explicit 'Set this to ensure all variable declared and consistent spelling
'Consider using WorkSheets collection rather than Sheets unless you have chart sheets as well?
Sub getViolations()
Dim Path As String 'Declare you other variables
Dim FileName As String
Path = "C:\Users\omartinr\Desktop\New folder (4)\New folder\"
FileName = Dir(Path & "*.xls")
Dim ws As Worksheet
Dim TxtRng As Range 'Declare this
Set ws = ThisWorkbook.Sheets("Sheet1")
Set TxtRng = ws.Range("A1:N1")
TxtRng.Font.ColorIndex = 2
TxtRng.Interior.ColorIndex = 5
TxtRng.Value = [{"Partition Name","Tag","EM Supply","SH Signal","PK","Sfactor","FiSH","RESCAL","RESCAL","RESCAL","RESCAL","RESCAL","RESCAL","RESCAL"}]
TxtRng.HorizontalAlignment = xlCenter
Dim i As Integer
i = 2
Do While FileName <> ""
Workbooks.Open FileName:=Path & FileName, ReadOnly:=True
Dim wc As Worksheet 'Consider whether to place these declarations just before the loop, avoids risk others may think there will be reinitialization even though there isn't
Set wc = ActiveWorkbook.Sheets("Violations Summary")
ws.Cells(i, 1).Value = wc.Range("B1") 'Use the wc variable
ws.Cells(i, 2).Value = wc.Range("C1")
Dim count As Integer
Dim sheetName As String, mySheetNameTest As String
Dim n As Integer
Dim exists As Boolean 'Corrected spelling
count = 15
For n = 3 To 14
If Not IsEmpty(wc.Cells(n, 2)) Then
If (wc.Cells(n, 2)) = 0 Then
ws.Cells(i, n).Font.ColorIndex = 4
ws.Cells(i, n).Value = wc.Cells(n, 2)
End If
If (wc.Cells(n, 2)) > 0 Then
Select Case wc.Cells(n, 1)
Case "PK"
sheetName = "Peak"
Case "Sfactor"
sheetName = "SF Supply"
Case Else
sheetName = wc.Cells(n, 1)
End Select
exists = sheetExists(sheetName)
If exists Then 'Shortened by removing = True (evaluates in same way)
ActiveWorkbook.Sheets(sheetName).Copy After:=ThisWorkbook.Sheets(1)
End If
ws.Cells(i, count) = wc.Cells(1, n).Value
ws.Cells(i, n).Font.ColorIndex = 3
ws.Cells(i, n).Value = wc.Cells(n, 2)
End If
If (wc.Cells(n, 2)) < 0 Then 'used wc variable
ws.Cells(i, n).Font.ColorIndex = 3
ws.Cells(i, n).Value = wc.Cells(n, 2)
End If
Else 'Simplified this as if is not empty then is empty so can use else
ws.Cells(i, n).Value = ["NA"] 'what is pupose of square brackets? These can be removed i think
End If
count = count + 1
Next n
Workbooks(FileName).Close
FileName = Dir()
i = i + 1
Loop
End Sub
Function sheetExists(sheetToFind As String) As Boolean
Dim Sheet As Worksheet ' declare
sheetExists = False
For Each Sheet In Worksheets
If sheetToFind = Sheet.Name Then
sheetExists = True
Exit Function
End If
Next Sheet
End Function
After you copy the ActiveWorkbook.Sheets(sheetName) to ThisWorkbook, ThisWorkbook becomes the ActiveWorkbook. ActiveWorkbook.Sheets(sheetName).Copy After:=ThisWorkbook.Sheets(1) should not throw an error but will probably cause ActiveWorkbook.Sheets("Violations Summary") to fail. For this reason, you should always fully qualify your references.
Some idealist programmers say that a subroutine should perform 1 simply task. Personally, I believe that if you have to scroll up, down, left or right to see what your code is doing it is time to refactor it. When refactoring I try to extract logical groups of tasks in a separate subroutine. This makes debugging and modifying the code far easier.
Refactored Code
Option Explicit
Sub getViolations()
Const Path As String = "C:\Users\omartinr\Desktop\New folder (4)\New folder\"
Dim n As Long
Dim Filename As String
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
Sheet1Setup ws
Filename = Dir(Path & "*.xls")
Do While Filename <> ""
ProcessWorkbook Filename, ws.Rows(n)
Filename = Dir()
Loop
End Sub
Sub ProcessWorkbook(WBName As String, row As Range)
Dim nOffset As Long, n As Long
Dim sheetName As String
Dim WB As Workbook
Set WB = Workbooks.Open(Filename:=Path & Filename, ReadOnly:=True)
With WB.Sheets("Violations Summary")
row.Columns(1).Value = .Range("B1")
row.Columns(2).Value = .Range("C1")
nOffset = 12
For n = 3 To 14
If .Cells(n, 2) = "" Then
row.Columns(n).Value = ["NA"]
ElseIf (.Cells(n, 2)) = 0 Then
row.Columns(n).Font.ColorIndex = 4
row.Columns(n).Font.ColorIndex = 0
ElseIf (.Cells(n, 2)) = 0 Then
Select Case wc.Cells(n, 1)
Case "PK"
sheetName = "Peak"
Case "Sfactor"
sheetName = "SF Supply"
Case Else
sheetName = wc.Cells(n, 1)
End Select
'Range.Parent refers to the ranges worksheet. row.Parent refers to ThisWorkbook.Sheets(1)
If SheetExists(WB, sheetName) Then .Copy After:=row.Parent.Sheets(1)
row.Columns(n + nOffset) = .Cells(1, n).Value
row.Columns(n).Font.ColorIndex = 3
row.Columns(n).Value = .Cells(n, 2)
End If
Next
End With
WB.Close SaveChanges:=False
End Sub
Function SheetExists(WB As Workbook, sheetToFind As String) As Boolean
Dim ws As Worksheet
For Each ws In WB.Worksheets
If sheetToFind = ws.Name Then
SheetExists = True
Exit Function
End If
Next
End Function
Sub Sheet1Setup(ws As Worksheet)
With ws.Range("A1:N1")
.Value = [{"Partition Name","Tag","EM Supply","SH Signal","PK","Sfactor","FiSH","RESCAL","RESCAL","RESCAL","RESCAL","RESCAL","RESCAL","RESCAL"}]
.Font.ColorIndex = 2
.Interior.ColorIndex = 5
.HorizontalAlignment = xlCenter
End With
End Sub
Note: row is the target Row of ThisWorkbook.Sheets(1). row.Columns(3) is a fancy way to write row.Cells(1, 3) which refers to the 3rd cell in the target row. Also note that Cells, Columns, and Rows are all relative to the range they belong to. e.g. Range("C1").Columns(2) refers to D1, Range("C1").Rows(2).Columns(2) refers to D2, Range("C1").Cells(2,2) also refers to D2.

Printing from ppt VBA to an Excel spreadsheet

I'm trying to convert excel VBA to ppt VBA. The original excel VBA (in "Comparison.xlsm") compared values from other excel workbooks and printed mismatching ones in Comparison.xlsm's Sheet1.
I know my code below (which is my ppt VBA version) is seeing the correct workbooks because when I use MsgBox to print values, I get the correct ones. However, my issue is when I try to print the incorrect values into Comparison.xlsm's Sheet1 at:
mainWB.Worksheets("Sheet1").Range("A" & nextCell).Value = ID_ISS
mainWB.Sheets("Sheet1").Range("B" & nextCell).Value = "Symbol"
mainWB.Sheets("Sheet1").Range("B" & nextCell).Value = "(FCST)"
I just don't see it print in the excel spreadsheet. Here's the relevant code:
EDIT: I changed it to add all my code -
Dim strIDRangeISS As String
Dim strIDRangeFCST As String
Dim iRow As Integer
Dim iCol As Integer
Dim ID_ISS As Long
Dim ID_FCST As Long
Dim nextCell As Integer
Dim iRowISS As Integer
Dim iRowFCST As Integer
Dim wbkFCST As Excel.Workbook
Dim wbkISS As Excel.Workbook
Dim mainWB As Excel.Workbook
Dim varSheetFCST As Excel.Worksheet
Dim varSheetISS As Excel.Worksheet
Dim mainWS As Excel.Worksheet
nextCell = 1
Set wbkFCST = Workbooks.Open("C:\Users\...\Documents\FCST.xlsx")
Set varSheetFCST = wbkFCST.Worksheets("Details")
Set wbkISS = Workbooks.Open(FileName:="C:\Users\...\Documents\ISS.xlsm")
Set varSheetISS = wbkISS.Worksheets("ISS")
Set mainWB = Workbooks.Open(FileName:="C:\Users\...\Documents\Comparison.xlsm")
Set mainWS = mainWB.Worksheets("Sheet1")
strIDRangeISS = "A2:D50"
strIDRangeFCST = "B2:I50"
'varSheetISS = varSheetISS.Range(strIDRangeISS)
'varSheetFCST = varSheetFCST.Range(strIDRangeFCST)
Dim ISSArray As Variant: ISSArray = varSheetISS.Range(strIDRangeISS)
Dim FCSTArray As Variant: FCSTArray = varSheetFCST.Range(strIDRangeFCST)
For iRowISS = LBound(ISSArray, 1) To UBound(ISSArray, 1) 'Goes down ISS' ID column
ID_ISS = ISSArray(iRowISS, 1)
MsgBox ("ID_ISS is " & ID_ISS)
For iRowFCST = LBound(FCSTArray, 1) To UBound(FCSTArray, 1) 'Goes down FCST ID column
ID_FCST = FCSTArray(iRowFCST, 1)
MsgBox ("ID_FCST is " & ID_FCST)
'Compares ISS ID to FCST ID till finds matching
If (ID_ISS = ID_FCST) Then
'If corr symbols aren't same, record ID in Comparison's spreadsheet and go onto next ISS ID
If (ISSArray(iRowISS, 3) <> FCSTArray(iRowFCST, 2)) Or (ISSArray(iRowISS, 4) <> FCSTArray(iRowFCST, 8)) Then
mainWB.Worksheets("Sheet1").Range("A" & nextCell).Value = ID_ISS
'Symbol mismatch
If (ISSArray(iRowISS, 3) <> FCSTArray(iRowFCST, 2)) Then
mainWB.Sheets("Sheet1").Range("B" & nextCell).Value = "Symbol"
End If
'(FCST) mismatch
If (ISSArray(iRowISS, 4) <> FCSTArray(iRowFCST, 8)) Then
mainWB.Sheets("Sheet1").Range("B" & nextCell).Value = "(FCST)"
End If
nextCell = nextCell + 1
End If
Exit For 'If corr symbols are same, go onto next ISS ID
End If
'Reached end of FCST ID's and no match -> record ISS ID
If iRowFCST = 49 Then
Workbooks("Comparison.xlsm").Sheets("Sheet1").Range("A" & nextCell).Value = ID_ISS
Workbooks("Comparison.xlsm").Sheets("Sheet1").Range("B" & nextCell).Value = "No corressponding Issue ID"
nextCell = nextCell + 1
Exit For
End If
Next iRowFCST
Next iRowISS

Excel VBA to select cells that contain a text string, and then copy and paste these cells into a new workbook

I am an avid excel user but not strong in vba. Any help is appreciated. Here are the steps that I am trying to do.
Find string of text in column B.
-Use offset to gather two values located around this string. offset(4,0) and offset(3,10)
- Do this a total of four times which gets us 8 values.
-paste the 8 values into 8 consecutive cells at the last row within another workbook
Set wkb = Excel.Workbooks.Open("c:\users\jojames\desktop\skillset performance with talktime.xls")
Set wks = wkb.Worksheets("Sheet1"): wks.Activate
find1Allscripts = "Allscripts - 10055"
Set Match1 = wks.Cells.Find(find1Allscripts)
findoffset1a = Match1.Offset(4, 0).Value
findoffset1b = Match1.Offset(3, 10).Value
find2Tier1 = "Tier1_ServiceDesk - 10052"
Set Match2 = wks.Cells.Find(find2Tier1)
findoffset2a = Match2.Offset(4, 0).Value
findoffset2b = Match2.Offset(3, 10).Value
find3Tier2 = "Tier2_ServiceDesk - 10053"
Set Match3 = wks.Cells.Find(find3Tier2)
findoffset3a = Match3.Offset(4, 0).Value
findoffset3b = Match3.Offset(3, 10).Value
find4Office = "Allscripts - 10055"
Set Match4 = wks.Cells.Find(find4Office)
findoffset4a = Match4.Offset(4, 0).Value
findoffset4b = Match4.Offset(3, 10).Value
'Paste the values'
Set wkb2 = ThisWorkbook
Set wks2 = wkb2.Sheets("ACD Data")
wks2.Activate
LastRow = wks2.Range("Y" & wks2.Rows.Count).End(xlUp).Row + 1
ActiveSheet.Range("Y" & LastRow).PasteSpecial xlPasteFormulas
Set wks = Nothing: Set wkb = Nothing
Set wks2 = Nothing: Set wkb2 = Nothing
I think this is a decent start. I would store what I was searching for in an array and loop through it
myArray = Array("Allscripts -1005", "Tier1_ServiceDesk - 10052", ...)
for i = lbound(myArray) to ubound(myArray)
Set Match1 = wks.Cells.Find(myArray(i))
if not Match1 is Nothing then
LastRow = wks2.Range("Y" & wks2.Rows.Count).End(xlUp).Row + 1
wks2.Range("Y" & LastRow) = Match1.Offset(4,0).Value
wks2.Range("Z" & LastRow) = Match1.Offset(3,10).Value
end if
next i
By the way, no need to select or activate anything. Just refer to it as an object like I did.

VBA Copying image to chart giving error

I'm writing a code to populate a data table then take and save an image of it by calling a module someone else made. My portion of the code is able to create the image and the sub that gets called works for creating images for other tables, but I think something is missing in my portion. This is the for loop to cycle through different product lines and create images of their tables.
For i = 0 To UBound(allLines)
Cells(bcell, 2) = Cells(product, 2)
Cells(bcell, 3) = Cells(product, 3)
Cells(bcell, 4) = Cells(product, 4)
Cells(bcell, 5) = Cells(product, 5)
Cells(ecell, 2) = Cells(product, 6)
Cells(ecell, 3) = Cells(product, 7)
Cells(ecell, 4) = Cells(product, 8)
Cells(ecell, 5) = Cells(product, 10)
Range(Cells(acell, 1), Cells(ecell, 5)).Select
Selection.Copy
Range("M14").Select
ActiveSheet.Pictures.Paste.Select
myfilename = Year(Now) & " " & MonthName(Month(Now)) & " " & allLines(i) & " Production Status Metrics" ' & ".jpg"
EndFilePath = "C:\Users\*******\Documents\**********\TEST FILES\" & myfilename 'edited for privacy
Call ExportMyPicture(allLines(i), EndFilePath) 'Module: Export_Cells_to_File
Range("A1").Select
acell = acell + 5
ecell = ecell + 5
bcell = bcell + 5
product = product + 1
Next
This is the sub that gets called up to the line that gives me an error
Sub ExportMyPicture(SelectedLine As String, EndFilePath As String)
Dim MyChart As String, MyPicture As String
Dim PicWidth As Long, PicHeight As Long
Application.ScreenUpdating = False
MyPicture = Selection.Name
With Selection
PicHeight = .ShapeRange.Height
PicWidth = .ShapeRange.Width
End With
Charts.Add
ActiveChart.Location Where:=xlLocationAsObject, Name:=SelectedLine & " Actions" 'This line gives the error
The error message reads object variable or with block variable not set
It seems that you are trying to make an embedded chart. In this case the chart has a container object called a chart object which sits between the chart and the containing sheet. Rather than creating a chart and then adjusting its location, you can add it as a chart object in the target sheet. Something like:
Sub test()
Dim mySheet As Worksheet
Set mySheet = Sheets(1)
Dim PicWidth As Long, PicHeight As Long
PicWidth = 200
PicHeight = 100
Dim CO As ChartObject
Dim CH As Chart
Set CO = mySheet.ChartObjects.Add(10, 10, PicWidth, PicHeight)
Set CH = CO.Chart
CH.ChartType = xlXYScatter
CO.Activate
End Sub
The 4 parameters of the Add method are left, top. width, height.

VBA copy a column from an excel's file to another in the first empty column

Private Sub CommandButton1_Click()
Dim selection As Variant
selection = UserForm1.ComboBox1.Text
Sheets("Sheet1").Select
Cells(1, 2) = selection
Sheets("Sheet1").Select
selection = Cells(1, 2)
namefile = "C:\Users\xxx\" & Left(selection, 1) & "\" & selection & ".xls"
Workbooks.Open Filename:=namefile
Dim wk1 As Workbook
Dim wk2 As Workbook
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Set wk1 = Workbooks("file1.xlsm")
Set wk2 = Workbooks(selection & ".xls")
Set sh1 = wk1.Worksheets("Sheet2")
Set sh2 = wk2.Worksheets("Sheet1")
sh2.Activate
Dim firstempty As Variant
Dim x As Integer
Dim y As Integer
Dim A1 As Variant
Dim R1 As Variant
Dim C1 As Variant
x = 0
y = 0
While x = 0
If Range(Cells(1, y), Cells(1, y)) <> "" Then
y = y + 1
Else: Range(Cells(1, y), Cells(1, y)).Select
A1 = Target.Address
R1 = Target.Row
C1 = Replace(A1, R1, "")
firstempty = (C1 & ":" & C1)
x = 1
End If
Wend
With sh1
.Columns("D:D").Copy Destination:=sh2.Range(firstempty)
End With
End
End Sub
I need to copy column D of Sheet2 file1.xls on the first blank column of sheet1 of a second file whose name is selected by a combobox.
I am having trouble defining the letter of the empty column of the second file.
I am getting runtime error 424 and my debugger brings me to the point in the code:
  A1 = Target.Address
What am I doing wrong?
Shouldn't y=0 be y=1 ?
Now you're referring to column 0.
And then this should work:
If Cells(1, y) <> "" Then
y = y + 1
Else
firstempty = y
x = 1
End If
And then:
.Columns("D:D").Copy Destination:=sh2.Columns(firstempty)
Here is a much faster way to get the last column:
Private Sub CommandButton1_Click()
Dim selection As Variant
selection = UserForm1.ComboBox1.Text
Sheets("Sheet1").Select
Cells(1, 2) = selection
Sheets("Sheet1").Select
selection = Cells(1, 2)
namefile = "C:\Users\xxx\" & Left(selection, 1) & "\" & selection & ".xls"
Workbooks.Open Filename:=namefile
Dim wk1 As Workbook
Dim wk2 As Workbook
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Set wk1 = Workbooks("file1.xlsm")
Set wk2 = Workbooks(selection & ".xls")
Set sh1 = wk1.Worksheets("Sheet2")
Set sh2 = wk2.Worksheets("Sheet1")
Dim LastColumn As Long
LastColumn = sh2.Cells(1, Columns.Count).End(xlToLeft).Column + 1
sh1.Columns("D:D").Copy sh2.Cells(, LastColumn)
End Sub
As a side note could you explain this part of code:
Sheets("Sheet1").Select
Cells(1, 2) = selection
Sheets("Sheet1").Select
selection = Cells(1, 2)
It looks like you are getting a value then assigning the value to a cell then the cells value (that you just assigned already) back to the variable that assigned the original value.
at the most you should only need one line:
Sheets("Sheet1").Cells(1, 2) = selection
dno't get the need for the rest.