vba excel: PasteSpecial for JPEG not working - vba

I have code that has been working, and all of the sudden it is not. I have tried everything and cannot figure out why. It works when I do a step by step (F8) but not when I run the code. What the code is doing is finding an ID in column B, and finding the jpg that has the same image (in the file H:\Images...) and pasting it into the 1st column. The code produces the error "Run-time error 1004: PasteSpecial method of worksheet class failed" and highlights the ActiveSheet.PasteSpecial line. Please help!
Sub Picture()
Dim picname As String
Dim lThisRow As Long
lThisRow = 3
Do While (Cells(lThisRow, 2) <> "")
Cells(lThisRow, 1).Select 'This is where picture will be inserted
picname = Cells(lThisRow, 2) 'This is the picture name
'MsgBox (picname)
Dim DirFile As String
DirFile = "H:\Images\9 Thumbnails\" & picname & ".jpg"
If Len(Dir(DirFile)) = 0 Then
'MsgBox "File does not exist"
Else
ActiveSheet.Pictures.Insert("H:\Images\9 Thumbnails\" & picname & ".jpg").Select
Selection.Cut
ActiveSheet.PasteSpecial Format:="Picture (JPEG)", Link:=False, _
DisplayAsIcon:=False
'Set WB = Workbooks.Open(DirFile)
With Selection
.ShapeRange.ScaleHeight 0.9, msoTrue
.Left = Cells(lThisRow, 1).Left + Cells(lThisRow, 1).Width / 2 - Selection.ShapeRange.Width / 2
.Top = Cells(lThisRow, 1).Top + Cells(lThisRow, 1).Height / 2 - Selection.ShapeRange.Height / 2
'.ShapeRange.LockAspectRatio = msoFalse
''.ShapeRange.Width = 80#
.ShapeRange.Rotation = 0#
End With
End If
lThisRow = lThisRow + 1
Loop
Range("B3").Select
On Error GoTo 0
Application.ScreenUpdating = True
Exit Sub
End Sub

I figured out the answer using .addpicture. This changes the way you have to look at dimensions, but I figured that out too. Final code:
Sub Picture()
Dim picname As String
Dim PicPath As String
Dim lThisRow As Long
Dim Pic As Shape
Dim rngPic As Range
lThisRow = 3
Do While (Cells(lThisRow, 2) <> "")
Set rngPic = Cells(lThisRow, 1) 'This is where picture will be inserted
picname = Cells(lThisRow, 2) 'This is the picture name
present = Dir("H:\Images\8 Thumbnails\" & picname & ".jpg")
PicPath = ("H:\Images\8 Thumbnails\" & picname & ".jpg")
If present <> "" Then
Set Pic = ActiveSheet.Shapes.AddPicture(PicPath, msoFalse, msoCTrue, 1, 1, -1, -1)
With Pic
.LockAspectRatio = msoTrue
If .Height < 45 Then .Height = 115
If .Width > 150 Then .Width = 150
.Left = rngPic.Left + rngPic.Width / 2 - Pic.Width / 2
.Top = rngPic.Top + rngPic.Height / 2 - Pic.Height / 2
End With
Else
Cells(lThisRow, 1) = ""
End If
lThisRow = lThisRow + 1
Loop
Range("B3").Select
On Error GoTo 0
Application.ScreenUpdating = True
Exit Sub
End Sub

Related

extracting the file and invoice from SAP

I have below code.
In first loop the excel file is extracted from the SAP - loop with variable a.
In the second loop (loop with variable k) the invoice is extracted from SAP (takes the order number from earlier extracted excel file).
The number of the order is taken from the excel file and paste to order in SAP.
Sometimes it happens, that order is either not taken from excel or not paste in SAP and the field for the order is empty.
This situation try to generates all the orders for the Controlling Area, which is very time-consuming (in fact it lasts hours).
I tried to add this line of code before the paste to the order, but of no result
Application.Wait Now + TimeValue("0:00:05")
Have you met this in your coding and could help with this?
extracting the excel file from SAP
Sub invoice_extr()
'##########################
'zapisuje pliki xlsx ordery
'##########################
Application.ScreenUpdating = False
SheetSrc = "Input data"
On Error Resume Next
If Not IsObject(SAPApplication) Then
Set SapGuiAuto = GetObject("SAPGUI")
If Err.Number <> 0 Then Exit Sub
Set SAPApplication = SapGuiAuto.GetScriptingEngine
If Err.Number <> 0 Then Exit Sub
End If
If Not IsObject(Connection) Then
Set Connection = SAPApplication.Children(0)
If Err.Number <> 0 Then
MsgBox ("Please, open SAP!")
Exit Sub
Else
End If
End If
If Not IsObject(session) Then
Set session = Connection.Children(0)
End If
On Error GoTo 0
Application.Wait (Now + TimeValue("0:00:01") / 1.5)
Dim a As Double
Dim last_row As Double
last_row = Cells(Rows.Count, 1).End(xlUp).Row
Range("b2:c" & last_row).Select
Selection.ClearContents
Dim path As String
path = Cells(2, 6)
For a = 2 To last_row
'###########################################################
'####SPRAWDZA CZY JEST JUZ PLIK XLSX O TAKIEJ NAZWIE########
'###########################################################
Dim objFSO_november1 As Object
Dim objFolder_november1 As Object
Dim objFile_november1 As Object
Dim objFile1_november1 As Object
Dim aa_november1 As Integer
Dim bb_november1 As Integer
Set objFSO_november1 = CreateObject("Scripting.FileSystemObject")
Set objFolder_november1 = objFSO_november1.GetFolder(path)
bb_november1 = 0
For Each objFile1_november1 In objFolder_november1.Files
bb_november1 = bb_november1 + 1
Next objFile1_november1
Dim myArray_november1() As Variant
ReDim Preserve myArray_november1(bb_november1, 1)
aa_november1 = 0
For Each objFile_november1 In objFolder_november1.Files
myArray_november1(aa_november1, 1) = objFile_november1.name
aa_november1 = aa_november1 + 1
Next objFile_november1
Dim aa As Double
Dim zz As Double
zz = 0
For aa = 0 To aa_november1 - 1
Dim how_many As Double
how_many = Len(Cells(a, 1))
'MsgBox (Cells(a, 1))
'MsgBox (Left(myArray_november1(aa, 1), how_many))
'MsgBox (aa)
If (Cells(a, 1) * 1) = (Left(myArray_november1(aa, 1), how_many) * 1) Then
Cells(a, 2) = "Done"
zz = zz + 1
'MsgBox (zz)
End If
If zz <> 0 Then
GoTo line1
End If
Next aa
Erase myArray_november1
If zz <> 0 Then
GoTo line1
End If
session.findById("wnd[0]").maximize
session.findById("wnd[0]/tbar[0]/okcd").Text = "/Ns_alr_87013019"
session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]/usr/txt$6-KOKRS").Text = Cells(a, 4)
Workbooks("Saving_invoice.xlsm").Activate
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").Text = Cells(a, 1)
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").SetFocus
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").caretPosition = 6
session.findById("wnd[0]/tbar[1]/btn[8]").press
'On Error GoTo line1
On Error Resume Next
session.findById("wnd[0]/shellcont/shell/shellcont[2]/shell").hierarchyHeaderWidth = 453
session.findById("wnd[0]/usr/lbl[62,8]").SetFocus
session.findById("wnd[0]/usr/lbl[62,8]").caretPosition = 9
session.findById("wnd[0]").sendVKey 2
session.findById("wnd[1]/usr/lbl[1,2]").SetFocus
session.findById("wnd[1]/usr/lbl[1,2]").caretPosition = 4
session.findById("wnd[1]").sendVKey 2
'################################################################
'#############WYBIERA LAYOUT /MACRO##############################
'################################################################
session.findById("wnd[0]/tbar[1]/btn[33]").press
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").currentCellRow = -1
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectColumn "VARIANT"
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").contextMenu
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectContextMenuItem "&FILTER"
session.findById("wnd[2]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").Text = "/MACRO"
session.findById("wnd[2]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").caretPosition = 6
session.findById("wnd[2]/tbar[0]/btn[0]").press
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectedRows = "0"
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").clickCurrentCell
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").currentCellColumn = "BELNR"
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").selectedRows = "0"
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").contextMenu
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").selectContextMenuItem "&XXL"
session.findById("wnd[1]/usr/cmbG_LISTBOX").SetFocus
session.findById("wnd[1]/usr/cmbG_LISTBOX").Key = "31"
session.findById("wnd[1]/tbar[0]/btn[0]").press
session.findById("wnd[1]/usr/ctxtDY_PATH").Text = path
Dim name As String
name = Cells(a, 1) & ".xlsx"
session.findById("wnd[1]/usr/ctxtDY_FILENAME").Text = name
session.findById("wnd[1]/usr/ctxtDY_FILENAME").caretPosition = 10
session.findById("wnd[1]/tbar[0]/btn[0]").press
'line1:
Application.Wait Now + TimeValue("0:00:05")
If Not Dir(path & name, vbDirectory) = vbNullString Then
Dim wB1 As Workbook
Dim ws1 As Worksheet
With Application
.DisplayAlerts = False
.EnableEvents = False
.ScreenUpdating = False
End With
Set wB1 = Workbooks.Open(path & name)
Set ws1 = wB.Sheets(1)
Application.Wait Now + TimeValue("0:00:05")
Workbooks(name).Activate
Workbooks(name).Close
Cells(a, 2) = "Done"
Else
Cells(a, 2) = "Please, check the order!"
End If
'Dim wB1 As Workbook
'Dim ws1 As Worksheet
'
' With Application
' .DisplayAlerts = False
' .EnableEvents = False
' .ScreenUpdating = False
' End With
'
' Set wB1 = Workbooks.Open(path & name)
' Set ws1 = wB.Sheets(1)
'
' Application.Wait Now + TimeValue("0:00:05")
'Workbooks(name).Activate
'
'Workbooks(name).Close
'
'Cells(a, 2) = "Checked"
line1:
Erase myArray_november1
Next a
Call invoice_extr_2
End Sub
extracting the invoice from SAP
Application.ScreenUpdating = False
SheetSrc = "Input data"
On Error Resume Next
If Not IsObject(SAPApplication) Then
Set SapGuiAuto = GetObject("SAPGUI")
If Err.Number <> 0 Then Exit Sub
Set SAPApplication = SapGuiAuto.GetScriptingEngine
If Err.Number <> 0 Then Exit Sub
End If
If Not IsObject(Connection) Then
Set Connection = SAPApplication.Children(0)
If Err.Number <> 0 Then
MsgBox ("Please, open SAP!")
Exit Sub
Else
End If
End If
If Not IsObject(session) Then
Set session = Connection.Children(0)
End If
On Error GoTo 0
Application.Wait (Now + TimeValue("0:00:01") / 1.5)
'####################################
'otwiera ordery i zapisuje faktury
'####################################
Workbooks("Saving_invoice.xlsm").Activate
Dim path As String
path = Cells(2, 6).Value
Dim last_row As Double
last_row = Cells(Rows.Count, 1).End(xlUp).Row
Dim i As Double
For i = 2 To last_row
Dim name2 As String
name2 = Cells(i, 1) & ".xlsx"
Dim wB2 As Workbook
Dim ws2 As Worksheet
If Not Dir(path & name2, vbDirectory) = vbNullString Then
With Application
.DisplayAlerts = False
.EnableEvents = False
.ScreenUpdating = False
End With
Set wB2 = Workbooks.Open(path & name2)
'Set ws2 = wB.Sheets(1)
Application.Wait Now + TimeValue("0:00:05")
Workbooks(name2).Activate
Else
GoTo line999999999
End If
Dim last_column As Integer
last_column = Cells(1, Columns.Count).End(xlToLeft).Column
'MsgBox (last_column)
Dim nr_kolumny As Long
nr_kolumny = Cells.Find(What:="Ref Document Number", SearchDirection:=xlPrevious, SearchOrder:=xlByColumns).Column
If Cells(1, last_column) = "action" Then
Dim ostatnia_kolumna As Integer
ostatnia_kolumna = Cells.Find(What:="action", SearchDirection:=xlPrevious, SearchOrder:=xlByColumns).Column
Else
ostatnia_kolumna = last_column + 1
End If
If Cells(1, last_column) = "action" Then
GoTo line2
Else
Cells(1, last_column + 1).Select
ActiveCell.FormulaR1C1 = "action"
End If
line2:
Dim k As Double
Dim last_row_document
last_row_document = Cells(Rows.Count, nr_kolumny).End(xlUp).Row - 2
For k = 2 To last_row_document
If Cells(k, ostatnia_kolumna) <> "Checked" Then
Workbooks("Saving_invoice").Activate
session.findById("wnd[0]").maximize
session.findById("wnd[0]/tbar[0]/okcd").Text = "/Ns_alr_87013019"
session.findById("wnd[0]").sendVKey 0
session.findById("wnd[0]/usr/txt$6-KOKRS").Text = Cells(i, 4)
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").Text = Cells(i, 1)
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").SetFocus
session.findById("wnd[0]/usr/ctxt_6ORDGRP-LOW").caretPosition = 6
session.findById("wnd[0]/tbar[1]/btn[8]").press
On Error Resume Next
session.findById("wnd[0]/shellcont/shell/shellcont[2]/shell").hierarchyHeaderWidth = 453
session.findById("wnd[0]/usr/lbl[62,8]").SetFocus
session.findById("wnd[0]/usr/lbl[62,8]").caretPosition = 9
session.findById("wnd[0]").sendVKey 2
session.findById("wnd[1]/usr/lbl[1,2]").SetFocus
session.findById("wnd[1]/usr/lbl[1,2]").caretPosition = 4
session.findById("wnd[1]").sendVKey 2
'#####################################################
'##############WYBIERA LAYOUT /MACRO##################
'#####################################################
session.findById("wnd[0]/tbar[1]/btn[33]").press
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").currentCellRow = -1
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectColumn "VARIANT"
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").contextMenu
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectContextMenuItem "&FILTER"
session.findById("wnd[2]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").Text = "/MACRO"
session.findById("wnd[2]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").caretPosition = 6
session.findById("wnd[2]/tbar[0]/btn[0]").press
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").selectedRows = "0"
session.findById("wnd[1]/usr/ssubD0500_SUBSCREEN:SAPLSLVC_DIALOG:0501/cntlG51_CONTAINER/shellcont/shell").clickCurrentCell
'######################################################
'############TUTAJ FILTROWANIE PO DOKUMENCIE###########
'######################################################
Workbooks(name2).Activate
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").setCurrentCell -1, "REFBN"
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").selectColumn "REFBN"
session.findById("wnd[0]/tbar[1]/btn[29]").press
session.findById("wnd[1]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").Text = Cells(k, nr_kolumny)
session.findById("wnd[1]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").caretPosition = 8
session.findById("wnd[1]/tbar[0]/btn[0]").press
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").currentCellColumn = "REFBN"
'session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").selectedRows = "0"
'session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").doubleClickCurrentCell
'###########################################################
'####SPRAWDZA CZY JEST JUZ PLIK O TAKIEJ NAZWIE#############
'###########################################################
Dim objFSO_november As Object
Dim objFolder_november As Object
Dim objFile_november As Object
Dim objFile1_november As Object
Dim aa_november As Integer
Dim bb_november As Integer
Set objFSO_november = CreateObject("Scripting.FileSystemObject")
Set objFolder_november = objFSO_november.GetFolder(path)
bb_november = 0
For Each objFile1_november In objFolder_november.Files
bb_november = bb_november + 1
Next objFile1_november
Dim myArray_november() As Variant
ReDim Preserve myArray_november(bb_november, 1)
aa_november = 0
For Each objFile_november In objFolder_november.Files
myArray_november(aa_november, 1) = objFile_november.name
aa_november = aa_november + 1
Next objFile_november
Dim z As Double
Dim how_digits As Double
how_digits = Len(Cells(k, nr_kolumny))
Dim s As Double
s = 0
For z = 0 To aa_november
If Left(myArray_november(z, 1), how_digits) = Cells(k, nr_kolumny) Then
s = s + 1
End If
Next z
Erase myArray_november
Dim h As Double
Dim o As Double
o = 0
For h = 2 To k
If Cells(h, nr_kolumny) = Cells(k, nr_kolumny) Then
o = o + 1
End If
Next h
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").selectedRows = o - 1 'tutaj nr linii po filtrowaniu
session.findById("wnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[1]/shell").doubleClickCurrentCell
session.findById("wnd[0]/titl/shellcont/shell").pressContextButton "%GOS_TOOLBOX"
session.findById("wnd[0]/titl/shellcont/shell").selectContextMenuItem "%GOS_VIEW_ATTA"
session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").pressToolbarContextButton "&MB_FILTER"
session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").selectContextMenuItem "&FILTER"
session.findById("wnd[2]/usr/subSUB_DYN0500:SAPLSKBH:0600/cntlCONTAINER1_FILT/shellcont/shell").currentCellRow = 2
session.findById("wnd[2]/usr/subSUB_DYN0500:SAPLSKBH:0600/cntlCONTAINER1_FILT/shellcont/shell").selectedRows = "2"
session.findById("wnd[2]/usr/subSUB_DYN0500:SAPLSKBH:0600/btnAPP_WL_SING").press
session.findById("wnd[2]/usr/subSUB_DYN0500:SAPLSKBH:0600/btn600_BUTTON").press
session.findById("wnd[3]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").Text = "Invoice"
session.findById("wnd[3]/usr/ssub%_SUBSCREEN_FREESEL:SAPLSSEL:1105/ctxt%%DYN001-LOW").caretPosition = 7
session.findById("wnd[3]/tbar[0]/btn[0]").press
session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").currentCellColumn = "BITM_DESCR"
session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").selectedRows = "0"
session.findById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").pressToolbarButton "%ATTA_EXPORT"
session.findById("wnd[2]/usr/ctxtDY_PATH").Text = path
If s = 0 Then
session.findById("wnd[2]/usr/ctxtDY_FILENAME").Text = Cells(k, nr_kolumny).Value & ".PDF"
Else
session.findById("wnd[2]/usr/ctxtDY_FILENAME").Text = Cells(k, nr_kolumny).Value & "-" & s + 1 & ".PDF"
End If
session.findById("wnd[2]/usr/ctxtDY_FILENAME").caretPosition = 5
session.findById("wnd[2]/tbar[0]/btn[0]").press
session.findById("wnd[1]/tbar[0]/btn[12]").press
Application.Wait Now + TimeValue("0:00:05")
Workbooks(name2).Activate
Cells(k, ostatnia_kolumna) = "Checked"
Workbooks(name2).Save
End If
Next k
Workbooks("Saving_invoice").Activate
Cells(i, 3) = "Checked"
Workbooks("Saving_invoice.xlsm").Save
Workbooks(name2).Save
Workbooks(name2).Close
line999999999:
Next i
Workbooks("Saving_invoice.xlsm").Activate
If Cells(1, 11) = "action" Then
Columns("K:K").Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Delete Shift:=xlToLeft
End If
Cells(1, 1).Activate
Workbooks("Saving_invoice.xlsm").Save
MsgBox ("Done")
End Sub
Well Application.Wait "The time at which you want the macro to resume, in Microsoft Excel date format." So it only pauses your VBA code but not "lets wait till some lines finishes work and we will continue" not sure how to write correctly :D bad in English. But hope you understood.
I suggest you to use Immediate window, and check everything is in place(values) with Debug.Print "My value: " & variable, also VBA is tricky and trying to make people less code while it automatically converts string, int and other stuff which is not declared or misspelled. So make on top "Option Explicit", then declare everything what is not declared.
And delete "On Error Resume Next", cause you cant see first error.

Insert inputboxes making code more interactive

I am currently working on the following code which is searching through all tabs in an excel workbook, selects all currencies greater a certain threshold in a defined column "J" and if criteria is met the line containing the currency that is greater threshold is pasted in a new created tab called "summary".
Now my question is:
1. Is there any chance to make this code more interactive? What I would like to do, is to add an inputbox in which the user is typing his threshold (in my example 1000000) and this threshold is used for looping through all tabs.
2. It would be great to get an input box like "select column containing currency", as column "J" won't be set all time, it could also be another column ("I", "M" etc) however this will be the same for all sheets then.
3. Any chance to select certain sheets within workbook (STRG + "sheetx" "sheety" etc....) which are then pasted into my loop and all others are neglected?
Any help, especially for my issues within question 1 and 2 is appreciated. Question 3 would only be a "nice-to-have" thing
Option Explicit
Sub Test()
Dim WS As Worksheet
Set WS = Sheets.Add
WS.Name = "Summary"
Dim i As Long, j As Long, lastRow As Long
Dim sh As Worksheet
With Sheets("Summary")
.Cells.Clear
End With
j = 2
For Each sh In ActiveWorkbook.Sheets
If sh.Name <> "Summary" Then
lastRow = sh.Cells(sh.Rows.Count, "A").End(xlUp).Row
For i = 4 To lastRow
If sh.Range("J" & i) > 1000000 Or sh.Range("J" & i) < -1000000 Then
sh.Range("a" & i & ":n" & i).Copy Destination:=Worksheets("Summary").Range("A" & j)
Sheets("Summary").Range("N" & j) = sh.Name
j = j + 1
End If
Next i
End If
Next sh
Sheets("Summary").Columns("A:N").AutoFit
End Sub
You may want to try this
Option Explicit
Sub Test()
Dim WS As Worksheet
Dim i As Long, j As Long, lastRow As Long
Dim sh As Worksheet
Dim sheetsList As Variant
Dim threshold As Long
Set WS = GetSheet("Summary", True)
sheetsList = Array("STRG","sheetx","sheety") '<--| fill this array with the sheets names to be looped through
threshold = Application.InputBox("Input threshold", Type:=1)
j = 2
For Each sh In ActiveWorkbook.Sheets(sheetsList)
lastRow = sh.Cells(sh.Rows.Count, "A").End(xlUp).Row
For i = 4 To lastRow
If sh.Range("J" & i) > threshold Or sh.Range("J" & i) < -threshold Then
sh.Range("a" & i & ":n" & i).Copy Destination:=WS.Range("A" & j)
WS.Range("N" & j) = sh.Name
j = j + 1
End If
Next i
Next sh
WS.Columns("A:N").AutoFit
End Sub
Function GetSheet(shtName As String, Optional clearIt As Boolean = False) As Worksheet
On Error Resume Next
Set GetSheet = Worksheets(shtName)
If GetSheet Is Nothing Then
Set GetSheet = Sheets.Add(after:=Worksheets(Worksheets.count))
GetSheet.Name = shtName
End If
If clearIt Then GetSheet.UsedRange.Clear
End Function
You can set a UserForm as input into the program - something like what follows. You only need to run the 'CreateUserForm' sub once to get the UserForm1 event handlers set up in your spreadsheet. Once that's done you can run the 'Test' to see the UserForm1 itself. You can edit the event handlers to check the user input or reject it if need be. Also once the UserForm1 is set up you can move the various labels and listboxes around and, of course, create new ones. It should look like this:
You can select as many sheets as required from the last listbox and the selections will be added to a vba Collection. See the MsgBox at the beginning of your code and play with entering values/selections into the user box to see what it does.
The UserForm handler that's called when you press the okay button will save the selections to global variables so that they can be picked up in the code.
Option Explicit
' Global Variables used by UserForm1
Public lst1BoxData As Variant
Public threshold As Integer
Public currencyCol As String
Public selectedSheets As Collection
' Only need to run this once. It will create UserForm1.
' If run again it will needlessly create another user form that you don't need.
' Once it's run you can modify the event handlers by selecting the UserForm1
' object in the VBAProject Menu by right clicking on it and selecting 'View Code'
' Note that you can select multiple Sheets on the last listbox of the UserForm
' simply by holding down the shift key.
Sub CreateUserForm()
Dim myForm As Object
Dim X As Integer
Dim Line As Integer
'This is to stop screen flashing while creating form
Application.VBE.MainWindow.Visible = False
Set myForm = ThisWorkbook.VBProject.VBComponents.Add(3)
'Create the User Form
With myForm
.Properties("Caption") = "Currency Settings"
.Properties("Width") = 322
.Properties("Height") = 110
End With
' Create Label for threshold text box
Dim thresholdLabel As Object
Set thresholdLabel = myForm.Designer.Controls.Add("Forms.Label.1")
With thresholdLabel
.Name = "lbl1"
.Caption = "Input Threshold:"
.Top = 6
.Left = 6
.Width = 72
End With
'Create TextBox for the threshold value
Dim thresholdTextBox As Object
Set thresholdTextBox = myForm.Designer.Controls.Add("Forms.textbox.1")
With thresholdTextBox
.Name = "txt1"
.Top = 18
.Left = 6
.Width = 75
.Height = 16
.Font.Size = 8
.Font.Name = "Tahoma"
.borderStyle = fmBorderStyleSingle
.SpecialEffect = fmSpecialEffectSunken
End With
' Create Label for threshold text box
Dim currencyLabel As Object
Set currencyLabel = myForm.Designer.Controls.Add("Forms.Label.1")
With currencyLabel
.Name = "lbl2"
.Caption = "Currency Column:"
.Top = 6
.Left = 100
.Width = 72
End With
'Create currency column ListBox
Dim currencyListBox As Object
Set currencyListBox = myForm.Designer.Controls.Add("Forms.listbox.1")
With currencyListBox
.Name = "lst1"
.Top = 18
.Left = 102
.Width = 52
.Height = 55
.Font.Size = 8
.Font.Name = "Tahoma"
.borderStyle = fmBorderStyleSingle
.SpecialEffect = fmSpecialEffectSunken
End With
' Create Label for sheet text box
Dim sheetLabel As Object
Set sheetLabel = myForm.Designer.Controls.Add("Forms.Label.1")
With sheetLabel
.Name = "lbl3"
.Caption = "Select Sheets:"
.Top = 6
.Left = 175
.Width = 72
End With
'Create currency column ListBox
Dim sheetListBox As Object
Set sheetListBox = myForm.Designer.Controls.Add("Forms.listbox.1")
With sheetListBox
.Name = "lst3"
.Top = 18
.Left = 175
.Width = 52
.Height = 55
.Font.Size = 8
.MultiSelect = 1
.Font.Name = "Tahoma"
.borderStyle = fmBorderStyleSingle
.SpecialEffect = fmSpecialEffectSunken
End With
'Create Select Button
Dim selectButton As Object
Set selectButton = myForm.Designer.Controls.Add("Forms.commandbutton.1")
With selectButton
.Name = "cmd1"
.Caption = "Okay"
.Accelerator = "M"
.Top = 30
.Left = 252
.Width = 53
.Height = 20
.Font.Size = 8
.Font.Name = "Tahoma"
.BackStyle = fmBackStyleOpaque
End With
' This will create the initialization sub and the click event
' handler to write the UserForm selections into the global
' variables so they can be used by the code.
myForm.CodeModule.InsertLines 1, "Private Sub UserForm_Initialize()"
myForm.CodeModule.InsertLines 2, " me.lst1.addItem ""Column I"" "
myForm.CodeModule.InsertLines 3, " me.lst1.addItem ""Column J"" "
myForm.CodeModule.InsertLines 4, " me.lst1.addItem ""Column M"" "
myForm.CodeModule.InsertLines 5, " me.lst3.addItem ""Sheet X"" "
myForm.CodeModule.InsertLines 6, " me.lst3.addItem ""Sheet Y"" "
myForm.CodeModule.InsertLines 7, " lst1BoxData = Array(""I"", ""J"", ""M"")"
myForm.CodeModule.InsertLines 8, "End Sub"
'add code for Command Button
myForm.CodeModule.InsertLines 9, "Private Sub cmd1_Click()"
myForm.CodeModule.InsertLines 10, " threshold = CInt(Me.txt1.Value)"
myForm.CodeModule.InsertLines 11, " currencyCol = lst1BoxData(Me.lst1.ListIndex)"
myForm.CodeModule.InsertLines 12, " Set selectedSheets = New Collection"
myForm.CodeModule.InsertLines 13, " For i = 0 To Me.lst3.ListCount - 1"
myForm.CodeModule.InsertLines 14, " If Me.lst3.Selected(i) = True Then"
myForm.CodeModule.InsertLines 15, " selectedSheets.Add Me.lst3.List(i)"
myForm.CodeModule.InsertLines 16, " End If"
myForm.CodeModule.InsertLines 17, " Next"
myForm.CodeModule.InsertLines 18, " Unload Me"
myForm.CodeModule.InsertLines 19, "End Sub"
'Add form to make it available
VBA.UserForms.Add (myForm.Name)
End Sub
' This is your code verbatim except for now
' the UserForm is shown for selecting the
' 1) currency threshold, 2) the column letter
' and 3) the sheets you want to process.
' The MsgBox just shows you what you've
' selected just to demonstrate that it works.
Sub Test()
Dim WS As Worksheet
Set WS = Sheets.Add
WS.Name = "Summary"
Dim i As Long, j As Long, lastRow As Long
Dim sh As Worksheet
With Sheets("Summary")
.Cells.Clear
End With
'**** Start: Running & Checking UserForm Output ****
UserForm1.Show
Dim colItem As Variant
Dim colItems As String
For Each colItem In selectedSheets:
colItems = colItems & " " & colItem
Next
MsgBox ("threshold=" & threshold & vbCrLf & _
"currencyCol=" & currencyCol & vbCrLf & _
"selectedSheets=" & colItems)
'**** End: Running & Checking UserForm Output ****
j = 2
For Each sh In ActiveWorkbook.Sheets
If sh.Name <> "Summary" Then
lastRow = sh.Cells(sh.Rows.Count, "A").End(xlUp).row
For i = 4 To lastRow
If sh.Range("J" & i) > 1000000 Or sh.Range("J" & i) < -1000000 Then
sh.Range("a" & i & ":n" & i).Copy Destination:=Worksheets("Summary").Range("A" & j)
Sheets("Summary").Range("N" & j) = sh.Name
j = j + 1
End If
Next i
End If
Next sh
Sheets("Summary").Columns("A:N").AutoFit
End Sub
The following code works for my purposes except the selection of single tabs to loop through:
Option Explicit
Sub Test()
Dim column As String
Dim WS As Worksheet
Dim i As Long, j As Long, lastRow As Long
Dim sh As Worksheet
Dim sheetsList As Variant
Dim threshold As Long
Set WS = GetSheet("Summary", True)
threshold = Application.InputBox("Input threshold", Type:=1)
column = Application.InputBox("Currency Column", Type:=2)
j = 2
For Each sh In ActiveWorkbook.Sheets
If sh.Name <> "Summary" Then
lastRow = sh.Cells(sh.Rows.Count, "A").End(xlUp).Row
For i = 4 To lastRow
If sh.Range(column & i) > threshold Or sh.Range(column & i) < -threshold Then
sh.Range("a" & i & ":n" & i).Copy Destination:=WS.Range("A" & j)
WS.Range("N" & j) = sh.Name
j = j + 1
End If
Next i
End If
Next sh
WS.Columns("A:N").AutoFit
End Sub
Function GetSheet(shtName As String, Optional clearIt As Boolean = False) As Worksheet
On Error Resume Next
Set GetSheet = Worksheets(shtName)
If GetSheet Is Nothing Then
Set GetSheet = Sheets.Add(after:=Worksheets(Worksheets.Count))
GetSheet.Name = shtName
End If
If clearIt Then GetSheet.UsedRange.Clear
End Function

VBA Selecting a range for multiple sheets

I am trying to use a sub routine to run through 10 team names in a sheet called Parameter. Each of the team names has its own sheet. I am trying to get the user to select the range and then have my sub run through and create charts for the 10 teams based on the range selected.
Sub test()
Dim rng As Range
Dim r As String
Application.ScreenUpdating = False
Dim TeamName As String
Set rng = Application.InputBox( _
Prompt:="Select a range.", _
Title:="Obtain Range Object", Type:=8)
r = "'" & TeamName & "'!" & rng.CurrentRegion.Address(ReferenceStyle:=xlR1C1)
For i = 1 To 10
TeamName = Sheets("Parameter").Range("E" & i).Value 'identify the location
Call charts(TeamName) ' Call subroutine
Next i
Application.ScreenUpdating = True
End Sub
Sub charts(TeamName As String)
Dim strTitle As Integer
Dim chtObj As ChartObject
Dim i As Integer
For Each chtObj In ActiveSheet.ChartObjects
chtObj.Delete
Next
For i = 1 To 42 Step 4
j = j + 1
Endrow = Range("A1").End(xlUp).Row - 1
Set Range1 = r.Offset(Endrow, i + 1)
Sheets(TeamName).Select
strTitle = j
MyFunction = ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlLineMarkers
ActiveChart.HasLegend = False
ActiveChart.HasTitle = True
ActiveChart.ChartTitle.Text = "PC " & j
ActiveChart.SetSourceData Source:=Range1
Dim MyWidth As Single, MyHeight As Single
Dim NumWide As Long
Dim iChtIx As Long, iChtCt As Long
MyWidth = 300
MyHeight = 200
NumWide = 5
iChtCt = ActiveSheet.ChartObjects.Count
For iChtIx = 1 To iChtCt
With ActiveSheet.ChartObjects(iChtIx)
.Width = MyWidth
.Height = MyHeight
.Left = ((iChtIx - 1) Mod NumWide) * MyWidth
.Top = Int((iChtIx - 1) / NumWide) * MyHeight
End With
Next
ActiveChart.SetElement (msoElementPrimaryCategoryAxisNone)
ActiveChart.SetElement (msoElementPrimaryValueGridLinesNone)
Next i
End Sub

Inserting a picture does not loop without adding the same picture into the same cell

I'm using the below code to add multiple pics in an excel file, but seem to be struggling around the For Loop for one, so I've tried the Do loop. The problem is that the same picture is added each time to the same cell when in fact, the following pics should be moved to the next range. Would really appreciate your input.
Sub ScopePics()
Dim fullpath, server, thefile, thisbook As String
Dim picname As String
Dim pic_location As String
Dim picnum As Integer
Dim picadd As String
Application.DisplayAlerts = False
File_name = Sheet2.Cells(3, 10)
pic_location = Sheet2.Cells(622, 10)
picname = Sheet2.Cells(623, 10)
pastePic = Sheet2.Cells(626, 10)
maxP = Sheet2.Cells(627, 10)
Scopebook = Sheet2.Cells(609, 10)
picnum = Sheet2.Cells(624, 10)
picadd = Sheet2.Cells(625, 10)
Do
Workbooks(Scopebook).Activate
Sheets("Scope of Work").Select
Range(pastePic).Select
'For x = 1 To maxP Step 1
'picadd = picnum + 1
Dim FS
Set FS = CreateObject("Scripting.FileSystemObject")
If FS.FileExists(pic_location) Then
ActiveSheet.Pictures.Insert(pic_location).Select
With Selection
.Left = Range(pastePic).Left + 5
.Top = Range(pastePic).Top + 5
.ShapeRange.LockAspectRatio = msoTrue
.ShapeRange.Height = 35#
.ShapeRange.Width = 45#
End With
ActiveSheet.Pictures(pic_location).Refresh 'Tried this to try to refresh but its not working.
End If
Windows(File_name).Activate
Sheets("Control").Select
Cells(624, 10).Value = Cells(624, 10).Value + 1
Calculate
Application.Wait (Now + #12:00:03 AM#) 'Tried this to see if the delay would help but still not working.
Calculate
ActiveSheet.Pictures.Insert(pic_location).Refresh
Workbooks(Scopebook).Activate
Loop Until picnum = picadd
ActiveWindow.Close
End Sub

Insert picture/icon in or over a cell

I hope I make this clear:
I have a loop that copies some hyperlinks in specific cells (they come from a document list with the file path, document name, etc stored in another sheet).
I would like to have an icon next to the hyperlink that indicates if it will open a word document, a folder, etc. In the document list, I can put an indicator in the column next to the hyperlink (1 for word doc, 2 for folder, etc) so that depending on the case, the right icon gets sent next to the right type of document hyperlink.
I have managed to do it by simply inserting shapes (blue rectangle for word doc, green for folder) but I'd like to have a more descriptive symbol (like a specific FaceID maybe?). Here is my code (dumbed down for simplicity):
Sub Icons()
Dim i As Integer
Dim sh As Object
'Only loops through A1:A5 for simplicity
'Looks at the associated indicator located in the previous sheet
'Assigns a shape depending if it is 1 or 2
For i = 1 To 5
If Feuil1.Range("A" & i) = "1" Then
Set sh = Feuil2.Shapes.AddShape(msoShapeRectangle, Range("A"& i).Left, Range("A" & i).Top, 15, 15)
sh.Name = "WordDocIcon" & i
sh.Fill.ForeColor.RGB = RGB(0, 220, 220)
End If
If Feuil1Range("A" & i) = "2" Then
'It is easy to do when inserting a given msoShape, but I want something else!
Set sh = Feuil2.Shapes.AddShape(msoShapeRectangle, Range("A" & i).Left, Range("A" & i).Top, 15, 15)
sh.Name = "FolderIcon" & i
sh.Fill.ForeColor.RGB = RGB(100, 100, 0)
End If
Next
End Sub
Further to my comments, Here is how you can insert pictures and position them in say Column B. I would still say that typing "Word" or "Folder" in Column B and then coloring the cell would be much simpler :)
Sub Sample()
Dim ws As Worksheet
Dim picWord As String
Dim picFolder As String
Dim Shp As Shape
Dim i As Long
picWord = "C:\Users\Siddharth\Desktop\Word.Jpg"
picFolder = "C:\Users\Siddharth\Desktop\folder.Jpg"
Set ws = ThisWorkbook.Sheets("Feuil1")
With ws
For i = 1 To 5
If .Range("A" & i) = "1" Then
With .Pictures.Insert(picWord)
With .ShapeRange
.LockAspectRatio = msoTrue
.Width = ws.Range("B" & i).Width
.Height = ws.Range("B" & i).Height
End With
.Left = ws.Range("B" & i).Left
.Top = ws.Range("B" & i).Top
.Placement = 1
.PrintObject = True
End With
ElseIf .Range("A" & i) = "2" Then
With .Pictures.Insert(picFolder)
With .ShapeRange
.LockAspectRatio = msoTrue
.Width = ws.Range("B" & i).Width
.Height = ws.Range("B" & i).Height
End With
.Left = ws.Range("B" & i).Left
.Top = ws.Range("B" & i).Top
.Placement = 1
.PrintObject = True
End With
End If
Next i
End With
End Sub
I used the following pictures. You can download these or use whatever you like.
When you run the above code, you will get this kind of output