VBA: Slow macro looping through paragraphs - vba

My macro in VBA Word 2016 (Win10) is verys slow for a 3-page document. What can I do to make it faster? Or is there another way I may count characters in paragraphs of different styles? I need to know how many characters are written in Normal style, H1-style etc.
Sub avsnittsteller()
'Optimize Code
Application.ScreenUpdating = False
'Rydd opp i formateringen
'Call stilFinner
intTittel = ActiveDocument.CustomDocumentProperties("malTittel").Value
intTittelI = ActiveDocument.CustomDocumentProperties("malTittelI").Value
intTittelX = ActiveDocument.CustomDocumentProperties("malTittelX").Value
intIngress = ActiveDocument.CustomDocumentProperties("malIngress").Value
intNormal = ActiveDocument.CustomDocumentProperties("malNormal").Value
'sett variablene til 0 før de avsnittene telles
Dim mlm(10) As String
tittel = 0
ingress = 0
mlm(1) = 0
mlm(2) = 0
mlm(3) = 0
mlm(4) = 0
mlm(5) = 0
mlm(6) = 0
mlm(7) = 0
' TELLE TEGN I ALLE AVSNITT
Dim Doc As Document
Set Doc = ActiveDocument
Dim para As Paragraph
Dim i As Long: i = 0
Dim j As Long: j = 0
Dim k As Long: k = 0
For Each para In Doc.Paragraphs
If para.Style = Doc.Styles("instruksjon") Or _
para.Style = Doc.Styles("Bildetekst") Or _
para.Style = Doc.Styles("Byline") Or _
para.Style = Doc.Styles("Byline email") Or _
para.Style = Doc.Styles("Fakta punkt") Or _
para.Style = Doc.Styles("tittel") Then
Else
If para.Style = Doc.Styles(wdStyleHeading1) Then
tittel = para.Range.Characters.Count - 1
Else
If para.Style = Doc.Styles(wdStyleHeading2) Then
ingress = para.Range.Characters.Count - 1
Else
If para.Style = Doc.Styles(wdStyleHeading3) Then
i = i + 1
mlm(i) = para.Range.Characters.Count - 1
Else
If para.Style = Doc.Styles(wdStyleNormal) Then
j = j + para.Range.Characters.Count - 1
End If 'N
End If 'H3
End If 'H2
End If 'H1
End If 'alle andre stiler
Next para
normal = j
'MsgBox "Tittelen din har " & tittel & " tegn" & vbCrLf & " ingress " & ingress & vbCrLf & " mlm-3 " & mlm(3) & vbCrLf & " mlm-4 " & mlm(4) & vbCrLf & "Alle normal " & normal
'MsgBox "Dokumentet blir nå lagret og antall tegn du har skrevet blir oppdatert øverst i dokumentet."
'MsgBox ActiveDocument.Paragraphs.Count
'DEFINER DOC PROPERTIES VARIABLENE
ActiveDocument.CustomDocumentProperties("tittel").Value = tittel
ActiveDocument.CustomDocumentProperties("ingress").Value = ingress
ActiveDocument.CustomDocumentProperties("mlm1").Value = mlm(1)
ActiveDocument.CustomDocumentProperties("mlm2").Value = mlm(2)
ActiveDocument.CustomDocumentProperties("mlm3").Value = mlm(3)
ActiveDocument.CustomDocumentProperties("mlm4").Value = mlm(4)
ActiveDocument.CustomDocumentProperties("mlm5").Value = mlm(5)
ActiveDocument.CustomDocumentProperties("mlm6").Value = mlm(6)
ActiveDocument.CustomDocumentProperties("mlm7").Value = mlm(7)
ActiveDocument.CustomDocumentProperties("normal").Value = j
ActiveDocument.Fields.Update 'OPPDATER ALLE FELT nb, virker ikke i bunn og topptekst
'MsgBox intTittelX
'Farg tittel og ingress rød om de er for lange, blå om de er passe korte
If tittel > intTittelX Then
With ActiveDocument.Styles(wdStyleHeading1).Font
.Color = wdColorRed
End With
Else
With ActiveDocument.Styles(wdStyleHeading1).Font
.Color = -738148353
End With
End If
If ingress > intIngress Then
With ActiveDocument.Styles(wdStyleHeading2).Font
.Color = wdColorRed
End With
Else
With ActiveDocument.Styles(wdStyleHeading2).Font
.Color = -738148353
End With
End If
'Optimize Code
Application.ScreenUpdating = True
End Sub

Try loading it into memory first, then taking action after the data has been loaded to an array. I just did a test with about 60 pages, it is taking about 8 seconds to populate the various attributes to an array. Once it's in the array, then manipulate it from there.
Here's the code:
Option Explicit
Public Sub test()
Debug.Print Now()
Dim doc As Document: Set doc = ActiveDocument
Dim i As Long
Dim myArr As Variant: ReDim myArr(1, 0 To doc.Paragraphs.Count - 1)
Dim para As Paragraph
For Each para In doc.Paragraphs
myArr(0, i) = para.Style
myArr(1, i) = para.Range.Characters.Count
i = i + 1
Next
Debug.Print Now()
Debug.Print myArr(0, 0), myArr(1, 0)
End Sub

I'm not sure if this is the proper way of doing this, but at least it works! I hope this code may help someone else looking for a way to loop through paragraphs and count the characters. Thank you Ryan!
Option Explicit
Public Sub avsnittsteller()
'http://stackoverflow.com/questions/42390551/vba-slow-macro-looping-through-paragraphs
Debug.Print Now()
Application.ScreenUpdating = True
'Rydd opp i formateringen
Call stilFinner
'deklarere variablene
Dim doc As Document: Set doc = ActiveDocument
Dim i As Long
Dim j As Long
Dim k As Long
Dim H1 As Long
Dim H2 As Long
Dim H3 As Long
Dim N As Long
Dim myArr As Variant: ReDim myArr(1, 0 To doc.Paragraphs.Count - 1)
Dim mlm(10) As String
Dim para As Paragraph
'Hent fram verdier i globale variabler som angir riktig lengde
intTittel = ActiveDocument.CustomDocumentProperties("malTittel").Value
intTittelI = ActiveDocument.CustomDocumentProperties("malTittelI").Value
intTittelX = ActiveDocument.CustomDocumentProperties("malTittelX").Value
intIngress = ActiveDocument.CustomDocumentProperties("malIngress").Value
intNormal = ActiveDocument.CustomDocumentProperties("malNormal").Value
'sett variablene til 0 før de avsnittene telles
tittel = 0
ingress = 0
mlm(1) = 0
mlm(2) = 0
mlm(3) = 0
mlm(4) = 0
mlm(5) = 0
mlm(6) = 0
mlm(7) = 0
'Lag en matrise (array) i minnet og kjør søket fra den
'Debug.Print doc.Paragraphs.Count
For Each para In doc.Paragraphs
myArr(0, i) = para.Style
myArr(1, i) = para.Range.Characters.Count - 1 'ComputeStatistics(wdStatisticCharacters)
i = i + 1
Next
'For hvert avsnitt fra 0 til antall avsnitt i dokumentet
For j = 0 To doc.Paragraphs.Count - 1
'Hvis avsnittets stil er Normal eller en av overskriftene så legg sammen alle tegnene
If myArr(0, j) = "Normal" Then
N = N + myArr(1, j)
'Debug.Print j, myArr(0, j), myArr(1, j)
End If
If myArr(0, j) = "Overskrift 1" Or myArr(0, j) = "Heading 1" Then
H1 = H1 + myArr(1, j)
'Debug.Print j, myArr(0, j), myArr(1, j)
End If
If myArr(0, j) = "Overskrift 2" Or myArr(0, j) = "Heading 2" Then
H2 = H2 + myArr(1, j)
'Debug.Print j, myArr(0, j), myArr(1, j)
End If
If myArr(0, j) = "Overskrift 3" Or myArr(0, j) = "Heading 3" Then
'Alle avsnitt med H3 telles ett og ett, summeres ikke
k = k + 1
mlm(k) = myArr(1, j)
Debug.Print j, myArr(0, j), myArr(1, j)
End If
Next j 'Neste avsnitt
'Debug.Print N & " " & H1 & " " & H2
'Debug.Print mlm(1) & " " & mlm(2) & " " & mlm(3) & " " & mlm(4) & " " & mlm(5)
'DEFINER DOC PROPERTIES VARIABLENE
ActiveDocument.CustomDocumentProperties("tittel").Value = H1
ActiveDocument.CustomDocumentProperties("ingress").Value = H2
ActiveDocument.CustomDocumentProperties("mlm1").Value = mlm(1)
ActiveDocument.CustomDocumentProperties("mlm2").Value = mlm(2)
ActiveDocument.CustomDocumentProperties("mlm3").Value = mlm(3)
ActiveDocument.CustomDocumentProperties("mlm4").Value = mlm(4)
ActiveDocument.CustomDocumentProperties("mlm5").Value = mlm(5)
ActiveDocument.CustomDocumentProperties("mlm6").Value = mlm(6)
ActiveDocument.CustomDocumentProperties("mlm7").Value = mlm(7)
ActiveDocument.CustomDocumentProperties("normal").Value = N
ActiveDocument.Fields.Update 'OPPDATER ALLE FELT nb, virker ikke i bunn og topptekst
'Farg tittel og ingress rød om de er for lange, blå om de er passe korte
If tittel > intTittelX Then
With ActiveDocument.Styles(wdStyleHeading1).Font
.Color = wdColorRed
End With
Else
With ActiveDocument.Styles(wdStyleHeading1).Font
.Color = -738148353
End With
End If
If ingress > intIngress Then
With ActiveDocument.Styles(wdStyleHeading2).Font
.Color = wdColorRed
End With
Else
With ActiveDocument.Styles(wdStyleHeading2).Font
.Color = -738148353
End With
End If
Application.ScreenUpdating = True
Debug.Print Now()
End Sub

Related

Type Mismatch in Dlookup

I'm getting a type mismatch in the Dlookup below. Note: the ID column in the Results2 Table is formatted as a Number.
If DLookup("[Result" & i & "]", "Results2", "[ID] = '" & newid & "'") <> Me.Controls("C" & 3 + column & "R" & i + j).Value Then
I've tried changing the newid from a string to an Integer or a Long, but I still get this error.
Full code for this Sub below, if more info is needed.
Private Sub BtnSave_Click()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim rs2 As DAO.Recordset
Dim rs3 As DAO.Recordset
Dim i As Integer
Dim j As Integer
Dim ans As Integer
Dim column As Integer
Dim colcnt As Integer
Dim newid As String
If IsNull(Me.Spindle3.Value) = False Then
colcnt = 3
ElseIf IsNull(Me.Spindle2.Value) = False Then
colcnt = 2
Else
colcnt = 1
End If
column = 1
Set db = CurrentDb
Set rs = db.OpenRecordset("Results")
Set rs2 = db.OpenRecordset("Results2")
Set rs3 = db.OpenRecordset("Results3")
Linestart:
j = 0
rs.AddNew
newid = rs![ID].Value
If Me.Result1.Value = "Fail" Or Me.Result2.Value = "Fail" Or Me.Result1.Value = "Fail" Then
If column = 1 Then
ans = MsgBox("This is a FAILING Result. Do you with to save it?", vbYesNo)
If ans = 7 Then GoTo Lineend
End If
ElseIf Me.Result1.Value = "Incomplete" Or Me.Result2.Value = "Incomplete" Or Me.Result2.Value = "Incomplete" Then
If column = 1 Then
ans = MsgBox("Testing is not finished for this part. Do you with to save and close now?", vbYesNo)
If ans = 7 Then GoTo Lineend
End If
End If
With rs
![PartNum] = Me.FilterPartNumber.Value
![INDNum] = Me.INDNum.Value
![DateTime] = Me.DateTime.Value
![HTLotNum] = Me.HTLotNum.Value
![Operator] = Me.Inspector.Value
![Spindle] = Me.Controls("Spindle" & column).Value
![TypeofCheck] = Me.InspType.Value
![OverallResult] = Me.Controls("Result" & column).Value
End With
rs2.AddNew
With rs2
![ID] = newid
![PartNum] = Me.FilterPartNumber.Value
![Plant] = Me.plantnum.Value
![DateTime] = Me.DateTime.Value
![HTLotNum] = Me.HTLotNum.Value
![Notes] = Me.Notes.Value
![Spindle] = Me.Spindle.Value
![TypeofCheck] = Me.InspType.Value
![OverallResult] = Me.Result1.Value
End With
rs3.AddNew
With rs3
![ID] = newid
![PartNum] = Me.FilterPartNumber.Value
![DateTime] = Me.DateTime.Value
End With
If IsNull(Me.HTLotNum.Value) = True Then
rs![HTLotNum] = "(blank)"
rs![HTLotNum] = "(blank)"
End If
For i = 1 To 90 Step 1
If i + j >= 90 Then
i = 90
GoTo Line1
End If
If IsNull(Me.Controls("C3R" & i + j).Value) = True Then
j = j + 1
End If
If i + j >= 90 Then
i = 90
GoTo Line1
End If
If IsNull(Me.Controls("C2R" & i + j).Value) = True Then GoTo Line1
rs("Char" & i) = Me!ListFeatures.column(1, i - 1)
rs("Desc" & i) = Me!ListFeatures.column(2, i - 1)
rs("Spec" & i) = Me!ListFeatures.column(3, i - 1) & " " & Me!ListFeatures.column(6, i - 1)
rs2("SC" & i) = Me!ListFeatures.column(4, i - 1)
rs2("Location" & i) = Me!ListFeatures.column(5, i - 1)
rs2("Result" & i) = Me.Controls("C" & 3 + column & "R" & i + j).Value
rs3("Coding" & i) = Me!ListCoding.column(1, i - 1)
Line1:
Next
rs.Update
rs2.Update
rs3.Update
For i = 1 To 90 Step 1
If i + j >= 90 Then
i = 90
GoTo Line1
End If
If IsNull(Me.Controls("C3R" & i + j).Value) = True Then
j = j + 1
End If
If i + j >= 90 Then
i = 90
GoTo Line1
End If
If DLookup("[Result" & i & "]", "Results2", "[ID] = '" & newid & "'") <> Me.Controls("C" & 3 + column & "R" & i + j).Value Then
MsgBox "Results not saved! Document results on paper and contact the database engineer regarding this error."
GoTo Lineend:
End If
Next
If column < colcnt Then
column = column + 1
GoTo Linestart
End If
Line2:
Forms![Landing Page]![LIstIncomplete].Requery
DoCmd.Close
Lineend:
End Sub
Per one of the comments, I updated the trouble line to the line below. I'm almost certain that was how I initially wrote this line and added the apostrophes as an attempt to fix.
If DLookup("[Result" & i & "]", "Results2", "[ID] = " & newid) <> Me.Controls("C" & 3 + column & "R" & i + j).Value Then
I had to fix one of my Goto's as well, one of them led to an infinite loop, but now everything is working as intended.
Thanks for the help!

PowerPoint VBA: "No currently active document window" upon closing the file

The script takes photos from the indicated folder and places them on slides according to the limit imposed by the user, e.g. 1000 photos / presentation. After that it has to create a new presentation.
It was working. But he stopped. Now I stop with a PowerPoint VBA error: "No currently active document window" at the moment when the script is to close the PowerPoint file and open a new one in which to continue saving the presentation.
Saving and closing a newly created presentation
Application.DisplayAlerts = ppAlertsNone
ActivePresentation.Save
ActiveWindow.Close <----- error here
Application.DisplayAlerts = ppAlertsAll
How to eliminate this error for the script to continue running?
All Code:
Option Explicit
Option Base 1
Option Private Module
Private il_plik As Integer
Private dostep_do_zdjec As Variant
Private tablica() As Variant
'Dla odwiedzających forum elektroda.pl - jeśli im się na coś przyda :)
Sub a_Dodaj_zdjecia_do_ppt()
Dim ogranicznik As Integer, roz_cznk_prw_str As Integer, roz_cznk_przezr As Integer
Dim plik As Integer, indeks As Integer, prezent As Integer, maks_zdj_prez As Integer
Dim maks_prez As Double
Dim cznk_prw_str As String, cznk_przezr As String, filterek As String, dostep_do_prez As String
Dim nazwa_prezent As String, nazwa_zdj As String, opis_zdj As String, prw_str As String
Dim opis_nagl_calej_prez As String, data_zdj As String, godzina_zdj As String
Dim info01 As String, info02 As String, info03 As String, info04 As String, info05 As String, info06 As String
Dim stempel_daty As Date
Dim il_zdj_w_prez As Variant
Dim nPrzezPrez As Object
'On Error GoTo koniec_blad
'-----------------------------------------------------------------------------------------------------------------------
'Ograniczenie maksymalnej ilości zdjęć na jedną prezentację
ogranicznik = 3000
'Ustawienia czcionki strony przewodniej - można sobie zmieniać poprzez tę zmienną
cznk_prw_str = "Arial" 'oryginalnie było "Calibri" - jednak ta czcionka z polskimi ą, ę, itd. nie wyświetlała się u mnie najlepiej
roz_cznk_prw_str = 36 '40
'Ustawienia czcionki strony przezrocza - można sobie zmieniać poprzez tę zmienną
cznk_przezr = "Arial" 'oryginalnie było "Calibri" - jednak ta czcionka z polskimi ą, ę, itd. nie wyświetlała się u mnie najlepiej
roz_cznk_przezr = 16 '18
'
'-----------------------------------------------------------------------------------------------------------------------
'
'Określenie opisu w nagłówku pojedynczej prezentacji - domyślne dla całej prezentacji
opis_nagl_calej_prez = Trim(InputBox("Proszę podać treść nagłówka dla przezroczy w prezentacji", "Treść nagłówka w prezentacji", "Zdjęcie wykonane w Kluczborku"))
'Określenie ilości zdjęć w pojedynczej prezentacji - domyślnie 500 szt.
il_zdj_w_prez = InputBox("Proszę podać ilość zdjęć na 1 prezentację", "Ilość zdjęć do umieszczenia w prezentacji", 500)
'Jeśli podano złą wartość
If il_zdj_w_prez = "" Or Not IsNumeric(Trim(il_zdj_w_prez)) Then
MsgBox "Podano złą wartość lub w ogóle jej nie podano" & vbCrLf & vbCrLf & "Koniec procedury", vbOKOnly + vbExclamation, "Uwaga !"
GoTo koniec
End If
'Jeśli podano dobrą wartość, ale w 'granicach przyzwoitości' typu Integer dla zmiennej 'ogranicznik'
il_zdj_w_prez = Abs(CInt(Trim(il_zdj_w_prez)))
If il_zdj_w_prez > ogranicznik Then
MsgBox "Przekroczono wartość graniczną" & vbCrLf & vbCrLf & "Koniec procedury", vbOKOnly + vbExclamation, "Uwaga !"
GoTo koniec
End If
'Określenie dostępu do katalogu ze zdjęciami
With Application.FileDialog(msoFileDialogFolderPicker)
filterek = ActivePresentation.Path
.AllowMultiSelect = False
.ButtonName = "Wybierz"
.InitialFileName = filterek
.Title = "Proszę wybrać katalog ze zdjęciami"
If .Show = -1 Then
dostep_do_zdjec = .SelectedItems(1)
Else
MsgBox "Nie podano dostępu do katalogu zdjęć" & vbCrLf & vbCrLf & "Koniec procedury", vbOKOnly + vbExclamation, "Uwaga !"
GoTo koniec
End If
End With
'Określenie dostępu do katalogu zapisywanych prezentacji
With Application.FileDialog(msoFileDialogFolderPicker)
filterek = ActivePresentation.Path
.AllowMultiSelect = False
.ButtonName = "Wybierz"
.InitialFileName = filterek
.Title = "Proszę podać miejsce zapisu prezentacji"
If .Show = -1 Then
dostep_do_prez = .SelectedItems(1)
Else
MsgBox "Nie podano dostępu do katalogu prezentacji" & vbCrLf & vbCrLf & "Koniec procedury", vbOKOnly + vbExclamation, "Uwaga !"
GoTo koniec
End If
End With
'Początek obróbki
MsgBox "Teraz rozpocznie się pobieranie nazw zdjęć" & vbCrLf & vbCrLf & "Może to trochę potrwać, zależnie od ich ilości", vbOKOnly, "Uwaga !"
'Pozyskanie nazw plików oraz ich posortowanie, wzrastająco, według daty utworzenia
'Pobrane zostaną tylko zdjęcia z rozszerzeniami: '*.bmp', '*.gif', '*.jpg', '*.jpeg', '*.png'
Call b_Lista_plikow_w_katalogu(dostep_do_zdjec)
Call c_sortowanie_babelkowe(tablica)
'Korekta liczby zdjęć w prezentacji, jeśli zadeklarowano większą ich ilość niż liczba wszystkich zdjęć do obróbki
If il_zdj_w_prez > il_plik Then il_zdj_w_prez = il_plik
'Określenie ilości prezentacji, jaka zostanie utworzona,
'w oparciu o ogólną ilość zdjęć i tych, przypadających na pojedynczą prezentację
maks_prez = (il_plik / il_zdj_w_prez) - Fix(il_plik / il_zdj_w_prez)
If maks_prez > 0 And maks_prez < 0.5 Then
maks_prez = Round(il_plik / il_zdj_w_prez, 0) + 1
Else
maks_prez = Round(il_plik / il_zdj_w_prez, 0)
End If
'Wartości początkowe zmiennych wyznaczających zakres 'od-do' zdjęć w prezentacji
maks_zdj_prez = il_zdj_w_prez
plik = 1
For prezent = 1 To maks_prez
'Utworzenie nazwy nowopowstającej prezentacji
Select Case prezent
Case Is <= 9: nazwa_prezent = "Prez_" & "000" & prezent & ".ppt"
Case Is <= 99: nazwa_prezent = "Prez_" & "00" & prezent & ".ppt"
Case Is <= 999: nazwa_prezent = "Prez_" & "0" & prezent & ".ppt"
Case Else: nazwa_prezent = "Prez_" & "" & prezent & ".ppt"
End Select
'Utworzenie i zapisanie na dysku nowopowstającej prezentacji - okno prezentacji widoczne - 'msoTrue'
Presentations.Add(WithWindow:=msoTrue).SaveAs dostep_do_prez & "\" & nazwa_prezent
'Zmiana wielkości okna programu
'ActiveWindow.View.Zoom = 75
'Wartość początkowa zmiennej ustalającej położenie danego przezrocza w prezentacji
indeks = 0
For plik = plik To maks_zdj_prez
'Wydzielenie nazwy kopiowanego zdjęcia oraz daty i godziny jego utworzenia
nazwa_zdj = Mid(tablica(plik), InStr(1, tablica(plik), ";", 1) + 1, Len(tablica(plik)) - InStr(1, tablica(plik), ";", 1))
stempel_daty = CDate(Mid(tablica(plik), 1, InStr(1, tablica(plik), ";", 1) - 1))
data_zdj = Format(stempel_daty, "dd.mm.yyyy")
godzina_zdj = Format(stempel_daty, "hh:mm")
'Zmienna na ewentualny, dodatkowy opis w nagłówku przezrocza pobrany z tablicy - tu niewykorzystana
opis_zdj = "Opis dodatkowy"
'Dodanie nowego przezrocza
indeks = indeks + 1
ActivePresentation.Slides.Add Index:=indeks, Layout:=ppLayoutBlank
'Przypisanie obiektu przezrocza do zmiennej - skrócenie zapisu obiektu
Set nPrzezPrez = ActivePresentation.Slides(indeks)
'Wkopiowanie zdjęcia
'LinkToFile:=msoFalse - teoretycznie uniezależnia wkopiowane zdjęcie od 'zdjęcia macierzystego' pobranego z katalogu
nPrzezPrez.Shapes.AddPicture FileName:=dostep_do_zdjec & "\" & nazwa_zdj, LinkToFile:=msoFalse, SaveWithDocument:=msoTrue, Left:=28, Top:=40, Width:=665, Height:=460
'Skalowanie wkopiowanego zdjęcia - zmianą liczby przy 'ScaleHeight' i 'ScaleWidth'
With nPrzezPrez.Shapes(1)
.LockAspectRatio = msoTrue
'.ScaleHeight 1.4, msoTrue, msoScaleFromMiddle 'msoScaleFromTopLeft 'msoScaleFromMiddle 'msoScaleFromBottomRight
'.ScaleWidth 1.4, msoTrue, msoScaleFromMiddle
.Width = 665
.Height = 460
End With
'Dodanie nagłówka
nPrzezPrez.Shapes.AddShape(msoShapeWave, 8.5, 9#, 703#, 62.38).TextFrame.TextRange.Text = "Zdjęcie nr " & Format(plik, "#,##0") & ": " & opis_nagl_calej_prez
'nPrzezPrez.Shapes.AddShape(msoShapeWave, 8.5, 9#, 703#, 62.38).TextFrame.TextRange.Text = "Zdjęcie nr " & Format(plik, "#,##0") & " (" & nazwa_zdj & ")"
'Inny układ opisu nagłówka - "Zdjęcie nr " & Format(plik, "#,##0") & ": " & nazwa_zdj & " - " & opis_zdj
'Formatowanie nagłówka
With nPrzezPrez.Shapes(2)
With .TextFrame
.AutoSize = ppAutoSizeNone
.WordWrap = msoFalse
With .TextRange
.ParagraphFormat.Alignment = ppAlignLeft
With .Font
.Name = cznk_przezr: .Size = roz_cznk_przezr: .Bold = msoTrue
.Color.RGB = RGB(0, 0, 0)
'.Color.SchemeColor = ppForeground
End With
End With
End With
With .Fill
.ForeColor.RGB = RGB(215, 228, 189)
.Solid
.Transparency = 0#
.Visible = msoTrue
End With
With .Line
.BackColor.RGB = RGB(255, 255, 255)
.ForeColor.RGB = RGB(79, 98, 40)
.Visible = msoTrue
End With
End With
'Dodanie stopki
nPrzezPrez.Shapes.AddShape(msoShapeWave, 8.5, 472#, 703#, 62.38).TextFrame.TextRange.Text = "DATA: " & data_zdj & ", godzina " & godzina_zdj
'Formatowanie stopki
With nPrzezPrez.Shapes(3)
With .TextFrame
.AutoSize = ppAutoSizeNone
.WordWrap = msoFalse
With .TextRange
.ParagraphFormat.Alignment = ppAlignLeft
With .Font
.Name = cznk_przezr: .Size = roz_cznk_przezr: .Bold = msoTrue
.Color.RGB = RGB(0, 0, 0)
'.Color.SchemeColor = ppForeground
End With
End With
End With
With .Fill
.ForeColor.RGB = RGB(215, 228, 189)
.Solid
.Transparency = 0#
.Visible = msoTrue
End With
With .Line
.BackColor.RGB = RGB(255, 255, 255)
.ForeColor.RGB = RGB(79, 98, 40)
.Visible = msoTrue
End With
End With
'Usunięcie dotychczasowych przypisań do zmiennych
Set nPrzezPrez = Nothing
nazwa_zdj = ""
stempel_daty = #1/1/1980#
data_zdj = ""
godzina_zdj = ""
opis_zdj = ""
'Co każde 1000 zdjęć 'odpuść' odrobinę na inne czynności - 'Niepraktyczne' w tym zadaniu
'If plik Mod 1000 = 0 Then DoEvents
Next plik
'Zmienna z tytułem prezentacji do strony przewodniej
prw_str = "PREZENTACJE" & vbCrLf & vbCrLf & "TYTUŁ" & vbCrLf & vbCrLf & "ILOŚĆ ZDJĘĆ: " & Format(indeks, "#,##0") & vbCrLf & vbCrLf & "OSTATNIA AKTUALIZACJA:" & vbCrLf & Format(Now(), "dd.mm.yyyy")
'Wstawienie strony przewodniej
ActivePresentation.Slides.Add Index:=1, Layout:=ppLayoutTitleOnly
'Sformatowanie strony przewodniej
With ActivePresentation.Slides(1).Shapes(1)
.Left = 54#
.Top = 167.75
.Width = 612.12
.Height = 115.62
With .TextFrame
.AutoSize = ppAutoSizeNone
.WordWrap = msoTrue
With .TextRange
.ParagraphFormat.Alignment = ppAlignCenter
.Text = prw_str
With .Font
.Name = cznk_prw_str: .Size = roz_cznk_prw_str
.Color.RGB = RGB(0, 0, 0)
'.Color.SchemeColor = ppForeground
End With
End With
End With
With .Fill
.Solid
.Transparency = 0#
.Visible = msoFalse
End With
With .Line
.Visible = msoFalse
End With
End With
'Zapis i zamknięcie nowoutworzonej prezentacji
Application.DisplayAlerts = ppAlertsNone
ActivePresentation.Save
' ActiveWindow.Close
ActivePresentation.Close
Application.DisplayAlerts = ppAlertsAll
'Czyszczenie zmiennej z tytułem prezentacji do strony przewodniej - na wszelki wypadek
prw_str = ""
'Jeśli przekroczono dopuszczalne wartości zmiennych, określone na początku, to korekta
'Można tu zastosować zmienną 'indeks'
maks_zdj_prez = il_zdj_w_prez + plik - 1
If maks_zdj_prez > il_plik Then maks_zdj_prez = il_plik
Next prezent
'Komunikat końcowy
info01 = "Procedura zakończona" & vbCrLf & vbCrLf
info02 = "Utworzono " & Format(maks_prez, "#,##0") & " prezentacje(-ę/-i) w: " & vbCrLf & vbCrLf
info03 = dostep_do_prez & vbCrLf & vbCrLf
info04 = "z " & Format(il_plik, "#,##0") & " zdjęć, po maksimum " & Format(il_zdj_w_prez, "#,##0") & " w każdej," & vbCrLf & vbCrLf
info05 = "pobranych z:" & vbCrLf & vbCrLf
info06 = dostep_do_zdjec
MsgBox info01 & info02 & info03 & info04 & info05 & info06, vbOKOnly, "Uwaga !"
Exit Sub
'Wykonaj jeśli w trakcie obróbki pojawił się jakiś błąd
koniec_blad:
On Error GoTo 0: On Error Resume Next
Application.DisplayAlerts = ppAlertsNone
With Presentations(nazwa_prezent)
.Saved = True: .Close
End With
Application.DisplayAlerts = ppAlertsAll
Set nPrzezPrez = Nothing
'Wykonaj po błędzie wyboru katalogu lub odwołaniu operacji ustalającej ilość zdjęć w prezentacji
koniec:
End
End Sub
Sub b_Lista_plikow_w_katalogu(dostep_do_zdjec As Variant)
Dim igt As Integer
Dim dlg As Integer, poz As Integer, licz As Integer
Dim rozsz_pliku As String
Dim ciag_prw As String, ciag_odtw As String, znak As String
Dim plik As Variant
Dim apli As Object, katalog As Object
On Error GoTo koniec
Set apli = CreateObject("Shell.Application")
Set katalog = apli.Namespace(dostep_do_zdjec)
'Inicjalizacja tablicy przechowującej dane o plikach zdjęć
ReDim tablica(1)
igt = 0
'Wpisanie informacji o plikach do tablicy
For Each plik In katalog.Items
'Wykonaj jeśli ma rozszerzenie
If InStrRev(plik, ".", -1, 1) <> 0 Then
rozsz_pliku = LCase(Mid(plik, InStrRev(plik, ".", -1, 1), 5))
'Pobierane będą dane tylko niektórych plików
If rozsz_pliku = ".jpg" Or rozsz_pliku = ".jpeg" Then
ciag_prw = CStr(katalog.GetDetailsOf(plik, 12))
'Dziwna wartość po wykonaniu <<katalog.GetDetailsOf(plik, 12)>>, tj. "?01-?03-?2017 ??19:21"
'Poniżej odtworzenie zapisu daty
dlg = Len(ciag_prw)
poz = 0
For licz = 1 To dlg
poz = poz + 1
znak = Mid(ciag_prw, poz, 1)
If Asc(znak) <> 63 Then ciag_odtw = ciag_odtw & znak
Next licz
If ciag_odtw = "" Then ciag_odtw = "01-01-1980 00:00"
igt = igt + 1
ReDim Preserve tablica(igt)
tablica(igt) = ciag_odtw & ";" & katalog.GetDetailsOf(plik, 0)
ciag_odtw = ""
Else
ciag_prw = CStr(katalog.GetDetailsOf(plik, 3))
If ciag_prw = "" Then ciag_prw = "01-01-1980 00:00"
igt = igt + 1
ReDim Preserve tablica(igt)
tablica(igt) = ciag_prw & ";" & katalog.GetDetailsOf(plik, 0)
ciag_prw = ""
End If
End If
Next plik
'Wstawia do zmiennej modułowej informację o ilości plików w tablicy
il_plik = igt
Set apli = Nothing
Set katalog = Nothing
Exit Sub
koniec:
Set apli = Nothing
Set katalog = Nothing
End Sub
Sub c_sortowanie_babelkowe(tablica As Variant)
Dim pocz As Integer, koniec As Integer
Dim i As Integer, j As Integer
Dim przech As Variant
On Error GoTo koniec
pocz = LBound(tablica)
koniec = UBound(tablica)
For i = pocz To koniec - 1
For j = i + 1 To koniec
If tablica(i) > tablica(j) Then
przech = tablica(j)
tablica(j) = tablica(i)
tablica(i) = przech
End If
Next j
Next i
Exit Sub
koniec:
End Sub
Edit://
I found a temporary solution to this. I fired this code, without the patch you wrote about on another computer, where I literally closed all windows in the window. Only the powerpoint was opened. The window with the script was on top. I didn't touch anything and the script worked fine on a large batch of photos (> 10k), creating a total of 11 presentation files. Can you explain to me as someone who is into programming and certainly VB programming does not know why this is happening and how to "remove" this problem?

Macro doesn't start with a button

I'm having an issue while i execute a macro.
When i execute it Line by line it works perfectly (Slow, but perfect).
But when i execute it with a Button in the graphic inteface, it doesn't even open the Excel File that is necessary to run the procedure.
Below i will link my code, because i don't even know what is happening.
I'm thinking that it must be some issue related with the weight of the procedure. But i don't know really.
Thank you by the way.
Sub Estructura_Activo_Fijo()
Application.AskToUpdateLinks = False
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Dim wbEstructura As Workbook
Dim wsTAG As Worksheet
Dim xWBName As String
Dim xWb As Workbook
Dim est
Dim consfinal
Dim boc
Dim bct
Dim consoc
On Error Resume Next
xWBName = "Estructura.xlsx"
Set wbEstructura = Application.Workbooks(xWBName)
If wbEstructura Is Nothing Then
Workbooks.Open Filename:=ActiveWorkbook.Path & "\Estructura.xlsx"
End If
On Error Resume Next
xWBName = "Consolidado Final.xlsx"
Set xWb = Application.Workbooks(xWBName)
If xWb Is Nothing Then
Workbooks.Open Filename:=ActiveWorkbook.Path & "\BBDD\Biblioteca\BBDD Locales\Consolidado Final.xlsx"
End If
On Error Resume Next
xWBName = "BBDD OC.xlsx"
Set xWb = Application.Workbooks(xWBName)
On Error Resume Next
If xWb Is Nothing Then
Workbooks.Open Filename:=ActiveWorkbook.Path & "\BBDD OC.xlsx"
End If
On Error Resume Next
xWBName = "BBDD CT.xlsx"
Set xWb = Application.Workbooks(xWBName)
If xWb Is Nothing Then
Workbooks.Open Filename:=ActiveWorkbook.Path & "\BBDD CT.xlsx"
End If
On Error Resume Next
xWBName = "Consolidado OC.xlsx"
Set xWb = Application.Workbooks(xWBName)
If wb Is Nothing Then
Workbooks.Open Filename:=ActiveWorkbook.Path & "\Consolidado OC.xlsx"
End If
ActiveWindow.WindowState = xlMinimized
Set wbEstructura = Workbooks("Estructura.xlsx")
Set wsTAG = wbEstructura.Worksheets("TAG")
Workbooks("Estructura.xlsx").Activate
Dim rng1 As Range, FSO
Dim rngTipo As Range
Dim i As Long
Dim j As Long
Dim k As Long
Dim error As Long
Dim existente As Long
Dim inicioTiempo As Double
Dim minutosTranscurridos As String
Set rng1 = wsTAG.Range("B2")
Set rngTipo = wsTAG.Range("AE2")
Set FSO = CreateObject("Scripting.FileSystemObject")
ruta = ActiveWorkbook.Path
inicioTiempo = Timer
rutaAño = ruta & "\2017"
rutaFARFI = rutaAño & "\FAR_FI"
rutaFARTA = rutaAño & "\FAR_TA"
rutaFARTN = rutaAño & "\FAR_TN"
rutaGOPMTI = rutaAño & "\GOPM_TI"
If Not FSO.FolderExists(rutaAño) Then
MkDir ruta & "\2017"
i = i + 1
Else
existente = existente + 1
MsgBox "La carpeta \2017 ya existe, el proceso se cerrará.", vbCritical
Exit Sub
End If
If Len(Dir(rutaFARFI, vbDirectory)) = 0 Then
MkDir rutaFARFI
Else
existente = existente + 1
End If
If Len(Dir(rutaFARTA, vbDirectory)) = 0 Then
MkDir rutaFARTA
Else
existente = existente + 1
End If
If Len(Dir(rutaFARTN, vbDirectory)) = 0 Then
MkDir rutaFARTN
Else
existente = existente + 1
End If
If Len(Dir(rutaGOPMTI, vbDirectory)) = 0 Then
MkDir rutaGOPMTI
Else
existente = existente + 1
End If
Do While Not IsEmpty(rng1)
If FSO.FolderExists(rutaAño) Then
v = rng1.Offset(0, 29).Value
Do While IsEmpty(rngTipo)
error = error + 1
Set rngTipo = rngTipo.Offset(1, 0)
Loop
If v = "Padre" Then 'Si 'v' es Padre:
If Not FSO.FolderExists(rutaFARFI & "\" & Left(v, 1) & rng1.Value2) Then
FSO.CreateFolder (rutaFARFI & "\" & Left(v, 1) & rng1.Value2)
i = i + 1
padre = padre + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaFARTA & "\" & Left(v, 1) & rng1.Value2) Then
FSO.CreateFolder (rutaFARTA & "\" & Left(v, 1) & rng1.Value2)
i = i + 1
padre = padre + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaFARTN & "\" & Left(v, 1) & rng1.Value2) Then
FSO.CreateFolder (rutaFARTN & "\" & Left(v, 1) & rng1.Value2)
i = i + 1
padre = padre + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaGOPMTI & "\" & Left(v, 1) & rng1.Value2) Then
FSO.CreateFolder (rutaGOPMTI & "\" & Left(v, 1) & rng1.Value2)
i = i + 1
padre = padre + 1
Else
existente = existente + 1
End If
rutaPadreFARFI = rutaFARFI & "\" & Left(v, 1) & rng1.Value
rutaPadreFARTA = rutaFARTA & "\" & Left(v, 1) & rng1.Value
rutaPadreFARTN = rutaFARTN & "\" & Left(v, 1) & rng1.Value
rutaPadreGOPMTI = rutaGOPMTI & "\" & Left(v, 1) & rng1.Value
ElseIf v = "Componente" Then
If Not FSO.FolderExists(rutaPadreFARFI & "\" & Left(v, 1) & rng1.Value) Then
FSO.CreateFolder (rutaPadreFARFI & "\" & Left(v, 1) & rng1.Value)
i = i + 1
componente = componente + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreFARTA & "\" & Left(v, 1) & rng1.Value) Then
FSO.CreateFolder (rutaPadreFARTA & "\" & Left(v, 1) & rng1.Value)
i = i + 1
componente = componente + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreFARTN & "\" & Left(v, 1) & rng1.Value) Then
FSO.CreateFolder (rutaPadreFARTN & "\" & Left(v, 1) & rng1.Value)
i = i + 1
componente = componente + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreGOPMTI & "\" & Left(v, 1) & rng1.Value) Then
FSO.CreateFolder (rutaPadreGOPMTI & "\" & Left(v, 1) & rng1.Value)
i = i + 1
componente = componente + 1
Else
existente = existente + 1
End If
rutaCompFARFI = rutaPadreFARFI & "\" & Left(v, 1) & rng1.Value
rutaCompFARTA = rutaPadreFARTA & "\" & Left(v, 1) & rng1.Value
rutaCompFARTN = rutaPadreFARTN & "\" & Left(v, 1) & rng1.Value
rutaCompGOPMTI = rutaPadreGOPMTI & "\" & Left(v, 1) & rng1.Value
End If
w = rng1.Offset(0, 1).Value
If v = "Padre" Then
If Not FSO.FolderExists(rutaPadreFARFI & "\" & w) Then
FSO.CreateFolder (rutaPadreFARFI & "\" & w)
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreFARFI & "\OC") Then
FSO.CreateFolder (rutaPadreFARFI & "\OC")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreFARFI & "\EP") Then
FSO.CreateFolder (rutaPadreFARFI & "\EP")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreFARFI & "\CAP") Then
FSO.CreateFolder (rutaPadreFARFI & "\CAP")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreFARTA & "\" & w) Then
FSO.CreateFolder (rutaPadreFARTA & "\" & w)
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreFARTA & "\OC") Then
FSO.CreateFolder (rutaPadreFARTA & "\OC")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreFARTA & "\EP") Then
FSO.CreateFolder (rutaPadreFARTA & "\EP")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreFARTA & "\CAP") Then
FSO.CreateFolder (rutaPadreFARTA & "\CAP")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreFARTN & "\" & w) Then
FSO.CreateFolder (rutaPadreFARTN & "\" & w)
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreFARTN & "\OC") Then
FSO.CreateFolder (rutaPadreFARTN & "\OC")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreFARTN & "\EP") Then
FSO.CreateFolder (rutaPadreFARTN & "\EP")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreFARTN & "\CAP") Then
FSO.CreateFolder (rutaPadreFARTN & "\CAP")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreGOPMTI & "\" & w) Then
FSO.CreateFolder (rutaPadreGOPMTI & "\" & w)
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreGOPMTI & "\OC") Then
FSO.CreateFolder (rutaPadreGOPMTI & "\OC")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreGOPMTI & "\EP") Then
FSO.CreateFolder (rutaPadreGOPMTI & "\EP")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaPadreGOPMTI & "\CAP") Then
FSO.CreateFolder (rutaPadreGOPMTI & "\CAP")
j = j + 1
Else
existente = existente + 1
End If
ElseIf v = "Componente" Then
If Not FSO.FolderExists(rutaCompFARFI & "\" & w) Then
FSO.CreateFolder (rutaCompFARFI & "\" & w)
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaCompFARFI & "\OC") Then
FSO.CreateFolder (rutaCompFARFI & "\OC")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaCompFARFI & "\EP") Then
FSO.CreateFolder (rutaCompFARFI & "\EP")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaCompFARFI & "\CAP") Then
FSO.CreateFolder (rutaCompFARFI & "\CAP")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaCompFARTA & "\" & w) Then
FSO.CreateFolder (rutaCompFARTA & "\" & w)
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaCompFARTA & "\OC") Then
FSO.CreateFolder (rutaCompFARTA & "\OC")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaCompFARTA & "\EP") Then
FSO.CreateFolder (rutaCompFARTA & "\EP")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaCompFARTA & "\CAP") Then
FSO.CreateFolder (rutaCompFARTA & "\CAP")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaCompFARTN & "\" & w) Then
FSO.CreateFolder (rutaCompFARTN & "\" & w)
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaCompFARTN & "\OC") Then
FSO.CreateFolder (rutaCompFARTN & "\OC")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaCompFARTN & "\EP") Then
FSO.CreateFolder (rutaCompFARTN & "\EP")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaCompFARTN & "\CAP") Then
FSO.CreateFolder (rutaCompFARTN & "\CAP")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaCompGOPMTI & "\" & w) Then
FSO.CreateFolder (rutaCompGOPMTI & "\" & w)
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaCompGOPMTI & "\OC") Then
FSO.CreateFolder (rutaCompGOPMTI & "\OC")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaCompGOPMTI & "\EP") Then
FSO.CreateFolder (rutaCompGOPMTI & "\EP")
j = j + 1
Else
existente = existente + 1
End If
If Not FSO.FolderExists(rutaCompGOPMTI & "\CAP") Then
FSO.CreateFolder (rutaCompGOPMTI & "\CAP")
j = j + 1
Else
existente = existente + 1
End If
End If
'-------------------------------------------------------------------'
'---Creación y Asignacion de carpeta para el archivo Excel Padre.---'
'-------------------------------------------------------------------'
Dim fi, tb As String
Dim TabName As String
TabName = rng1.Value
rutaFichas = ActiveWorkbook.Path & "\BBDD\Fichas SGM"
If v = "Padre" Then
If rutaPadreFARFI = rutaFARFI & "\" & "P" & TabName Then
fi = "FAR - FIN.xlsm"
Workbooks.Open Filename:=rutaFichas & "\" & fi
Range("D5").Value = TabName
ActiveSheet.Name = TabName
With ThisWorkbook
.Worksheets(TabName).Copy
ActiveSheet.Cells.Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlValues
.Worksheets(TabName).Copy After:=ActiveWorkbook.Worksheets(ActiveWorkbook.Worksheets.Count)
ActiveSheet.Cells.Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlValues
End With
With ThisWorkbook
.Worksheets("Distribucion").Copy
ActiveSheet.Cells.Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlValues
.Worksheets("Distribucion").Copy After:=ActiveWorkbook.Worksheets(ActiveWorkbook.Worksheets.Count)
ActiveSheet.Cells.Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlValues
End With
Application.CutCopyMode = False
ActiveWorkbook.SaveAs Filename:=rutaPadreFARFI & "\" & TabName
ActiveWorkbook.Close SaveChanges:=True
k = k + 1
End If
If rutaPadreFARTA = rutaFARTA & "\" & "P" & TabName Then
tb = "FAR - TRIB.xlsm"
Workbooks.Open Filename:=rutaFichas & "\" & tb
Range("D5").Value = TabName
ActiveSheet.Name = TabName
With ThisWorkbook
.Worksheets(TabName).Copy
ActiveSheet.Cells.Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlValues
.Worksheets(TabName).Copy After:=ActiveWorkbook.Worksheets(ActiveWorkbook.Worksheets.Count)
ActiveSheet.Cells.Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlValues
End With
With ThisWorkbook
.Worksheets("Distribucion").Copy
ActiveSheet.Cells.Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlValues
.Worksheets("Distribucion").Copy After:=ActiveWorkbook.Worksheets(ActiveWorkbook.Worksheets.Count)
ActiveSheet.Cells.Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlValues
End With
Application.CutCopyMode = False
ActiveWorkbook.SaveAs Filename:=rutaPadreFARTA & "\" & TabName
ActiveWorkbook.Close SaveChanges:=True
k = k + 1
End If
If rutaPadreFARTN = rutaFARTN & "\" & "P" & TabName Then
tb = "FAR - TRIB.xlsm"
Workbooks.Open Filename:=rutaFichas & "\" & tb
Range("D5").Value = TabName
ActiveSheet.Name = TabName
With ThisWorkbook
.Worksheets(TabName).Copy
ActiveSheet.Cells.Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlValues
.Worksheets(TabName).Copy After:=ActiveWorkbook.Worksheets(ActiveWorkbook.Worksheets.Count)
ActiveSheet.Cells.Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlValues
End With
With ThisWorkbook
.Worksheets("Distribucion").Copy
ActiveSheet.Cells.Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlValues
.Worksheets("Distribucion").Copy After:=ActiveWorkbook.Worksheets(ActiveWorkbook.Worksheets.Count)
ActiveSheet.Cells.Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlValues
End With
Application.CutCopyMode = False
ActiveWorkbook.SaveAs Filename:=rutaPadreFARTN & "\" & TabName
ActiveWorkbook.Close SaveChanges:=True
k = k + 1
End If
If rutaPadreGOPMTI = rutaGOPMTI & "\" & "P" & TabName Then
tb = "FAR - TRIB.xlsm"
Workbooks.Open Filename:=rutaFichas & "\" & tb
Range("D5").Value = TabName
ActiveSheet.Name = TabName
With ThisWorkbook
.Worksheets(TabName).Copy
ActiveSheet.Cells.Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlValues
.Worksheets(TabName).Copy After:=ActiveWorkbook.Worksheets(ActiveWorkbook.Worksheets.Count)
ActiveSheet.Cells.Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlValues
End With
With ThisWorkbook
.Worksheets("Distribucion").Copy
ActiveSheet.Cells.Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlValues
.Worksheets("Distribucion").Copy After:=ActiveWorkbook.Worksheets(ActiveWorkbook.Worksheets.Count)
ActiveSheet.Cells.Copy
ActiveSheet.Range("A1").PasteSpecial Paste:=xlValues
End With
Application.CutCopyMode = False
ActiveWorkbook.SaveAs Filename:=rutaPadreGOPMTI & "\" & TabName
ActiveWorkbook.Close SaveChanges:=True
k = k + 1
End If
End If
Set rng1 = rng1.Offset(1, 0)
Set rngTipo = rngTipo.Offset(1, 0)
End If
Loop
Workbooks("Consolidado Final.xlsx").Close
Workbooks("Consolidado OC.xlsx").Close
Workbooks("BBDD CT.xlsx").Close
Workbooks("BBDD OC.xlsx").Close
minutosTranscurridos = Format((Timer - inicioTiempo) / 86400, "hh:mm:ss")
Set FSO = Nothing
'Se reactiva la propiedad de actualización.}
Application.ScreenUpdating = True
ActiveWindow.WindowState = xlMaximized 'Se maximiza la ventana para mostrar el menu
End Sub
Here is an example of how you might split your code into useful VBA components. Define "useful" as something that does more work for you than it eats up of your time.
Option Explicit
Sub Estructura_Activo_Fijo()
Dim WbEstructura As Workbook
Dim WbX As Workbook
Application.ScreenUpdating = False
If Not GetWorkbook("Estructura.xlsx", WbEstructura) Then GoTo SideExit
If Not GetWorkbook("BBDD\Biblioteca\BBDD Locales\Consolidado Final.xlsx", WbX) Then GoTo SideExit
SideExit:
Application.ScreenUpdating = True
End Sub
Private Function GetWorkbook(ByVal FilePath As String, _
Wb As Workbook) As Boolean
Dim Sp() As String ' split FilePath
Dim Ffn As String ' Full File Name
Dim Fn As String ' File name
Sp = Split(FilePath, "\")
Fn = Sp(UBound(Sp))
On Error Resume Next
Set Wb = Application.Workbooks(Fn)
If Err.Number = 9 Then ' 9 = Suscript out of range
Ffn = ActiveWorkbook.Path & "\" & FilePath
If Len(Dir(Ffn)) = 0 Then
MsgBox "I couldn't find the file" & vbCr & _
FilePath & vbCr & _
"This task must now be abandoned.", _
vbCritical, "Unable to open workbook"
Else
Set Wb = Workbooks.Open(FileName:=Ffn)
End If
End If
GetWorkbook = Not (Wb Is Nothing)
End Function
In this example, I created one function which opens a workbook. You can call it repeatedly for the many workbooks you need to open. All the work is done in the function. In the main procedure opening two workbooks just takes 2 lines of code.
You will notice that the function can do a much better job by itself than if it were part of the main. It can tell you what went wrong. Moreover, it returns TRUE if the workbook was successfully opened, and your main procedure can take action depending upon that event much easier and more transparently.

Runtime 1004: method saveas of object _workbook failed

I have some problem with Excel macro...
When I run this script I received
error runtime 1004: method save as of object _workbook failed
One month ago this macro worked good.... Where is the problem?
I did not do a program this script, I found it already used in the station of my old colleague, and so far has ever given no problem ....
Thanks for help
Sub StampaVodafone()
Dim i, j As Integer
Dim Fogliotmp As Worksheet
Dim ContoVodafone As String
Dim FoglioElenco As Worksheet
Dim Percorsofile As String
Dim PercorsoSalva As String
Dim ValCell As Variant
Dim strTesto As String
strTesto = "Vuoi procedere con la stampa ?" & vbCr & "SI - Per procedere con la stampa dei dettagli telefonici" & _
vbCr & "NO - Per andare alla procedura successiva"
If MsgBox(strTesto, 68, "Avvio StampaVodafone") = vbYes Then
'Procedura di stampa documenti
i = 1
Do
Set Fogliotmp = ActiveWorkbook.Worksheets(i)
If UCase(Mid(Fogliotmp.Name, 1, 3)) = "TEL" Or UCase(Mid(Fogliotmp.Name, 1, 3)) = "LA " Then
'Trovo dove sta la fine pagina
j = 15
ValCell = Mid(CStr(Fogliotmp.Cells(j, 1).Value), 1, 12)
Do While (UCase(ValCell) <> "TOTALE COSTI")
j = j + 1
ValCell = Mid(CStr(Fogliotmp.Cells(j, 1).Value), 1, 12)
Loop
With Fogliotmp.PageSetup
.LeftMargin = 0
.RightMargin = 0
.TopMargin = 0
.BottomMargin = 0
.PrintArea = "$A$1:$P$" & CStr(j)
.LeftHeader = ""
.CenterHeader = ""
.RightHeader = ""
.LeftFooter = ""
.CenterFooter = ""
.RightFooter = ""
.LeftMargin = Application.InchesToPoints(0)
.RightMargin = Application.InchesToPoints(0)
.TopMargin = Application.InchesToPoints(0)
.BottomMargin = Application.InchesToPoints(0)
.HeaderMargin = Application.InchesToPoints(0.511811023622047)
.FooterMargin = Application.InchesToPoints(0.511811023622047)
.PrintHeadings = False
.PrintGridlines = False
.PrintComments = xlPrintNoComments
.PrintQuality = 600
.CenterHorizontally = False
.CenterVertically = False
.Orientation = xlPortrait
.Draft = False
.PaperSize = xlPaperA4
.FirstPageNumber = xlAutomatic
.Order = xlDownThenOver
.BlackAndWhite = False
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = 1
.PrintErrors = xlPrintErrorsDisplayed
.OddAndEvenPagesHeaderFooter = False
.DifferentFirstPageHeaderFooter = False
.ScaleWithDocHeaderFooter = True
.AlignMarginsHeaderFooter = False
.EvenPage.LeftHeader.Text = ""
.EvenPage.CenterHeader.Text = ""
.EvenPage.RightHeader.Text = ""
.EvenPage.LeftFooter.Text = ""
.EvenPage.CenterFooter.Text = ""
.EvenPage.RightFooter.Text = ""
.FirstPage.LeftHeader.Text = ""
.FirstPage.CenterHeader.Text = ""
.FirstPage.RightHeader.Text = ""
.FirstPage.LeftFooter.Text = ""
.FirstPage.CenterFooter.Text = ""
.FirstPage.RightFooter.Text = ""
End With
Application.PrintCommunication = True
Fogliotmp.PrintOut
End If
i = i + 1
Set Fogliotmp = Nothing
Loop While (i < ActiveWorkbook.Worksheets.Count + 1)
MsgBox "Ho terminato di stampare", vbExclamation, "MACRO SONIA"
'Fine procedura stampa
End If
'--
strTesto = "Vuoi procedere con l'estrazione dei file XLSX da spedire agli utenti?" & vbCr & _
"SI - Inizia la generazione dei file XLSX" & vbCr & _
"NO - Termina la macro"
If MsgBox(strTesto, 68, "Genera XLS") = vbYes Then
'Inizio estrazione
Percorsofile = "H:\Vodafone\ElencoCellEstrazione.xlsx"
PercorsoSalva = "H:\Vodafone\Estratti\"
ContoVodafone = Application.ActiveWorkbook.Name
'--
Set FoglioElenco = Workbooks.Open(Percorsofile).Worksheets(1)
'--
i = 1
Do
Windows(ContoVodafone).Activate
Set Fogliotmp = ActiveWorkbook.Worksheets(i)
If UCase(Mid(Fogliotmp.Name, 1, 3)) = "TEL" Then
strTesto = Trim(Mid(Fogliotmp.Name, 4, Len(Fogliotmp.Name)))
'Cerco il nome della persona
j = 2
ValCell = Trim(CStr(FoglioElenco.Cells(j, 1).Value))
Do While (UCase(ValCell) <> UCase(strTesto) And UCase(ValCell) <> "END LIST")
j = j + 1
ValCell = Trim(CStr(FoglioElenco.Cells(j, 1).Value))
Loop
If UCase(ValCell) <> "END LIST" Then
'Ho il nome dell'intestatario del telefono
ValCell = Trim(CStr(FoglioElenco.Cells(j, 2).Value))
strTesto = PercorsoSalva & ValCell
'Salvo il documento
Windows(ContoVodafone).Activate
Sheets(Fogliotmp.Name).Select
Sheets(Fogliotmp.Name).Copy
ActiveWorkbook.SaveAs Filename:=strTesto, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
ActiveWindow.Close
Windows(ContoVodafone).Activate
End If
End If
'--
i = i + 1
Set Fogliotmp = Nothing
Windows(ContoVodafone).Activate
Loop While (i < ActiveWorkbook.Worksheets.Count + 1)
MsgBox "Ho terminato gli export XlsX", vbExclamation, "MACRO SONIA"
End If
End Sub
You should debug the value of strTesto. Check if it's not null and if it has the extension correct (.xlsm)
TIP: How to debug in
excel

Having trouble with the Dim and Set command in VBA, compile error "mismatch"

Writing a short script in VBA to sort through data, essentially counting the number of names entered into a list, and printing them into a new column. However, the & in the row "Set Staff 1" is causing a compile error due to a mismatch. It seems to be caused by setting two ranges at the same time. I get the impression that there's a straightforward solution...
Sub Staffing()
Dim Rng As Range
Dim i As Long
Dim Staff1 As Range
Dim Staff2 As Range
Dim Staff3 As Range
Dim Staff4 As Range
Dim Staff5 As Range
Dim Staff6 As Range
Dim Staff7 As Range
While i <= 300
Set Rng = Range("J" & i)
Set Staff1 = ("X" & i)
Set Staff2 = ("AD" & i)
Set Staff3 = ("AJ" & i)
Set Staff4 = ("AP" & i)
Set Staff5 = ("BB" & i)
Set Staff6 = ("BH" & i)
Set Staff7 = ("BN" & i)
If Staff1 <> "" Then
Rng.FormulaR1C1 = "0"
i = i + 1
If Staff2 <> "" Then
Rng.FormulaR1C1 = "1"
i = i + 1
If Staff3 <> "" Then
Rng.FormulaR1C1 = "2"
i = i + 1
If Staff4 <> "" Then
Rng.FormulaR1C1 = "3"
i = i + 1
If Staff5 <> "" Then
Rng.FormulaR1C1 = "4"
i = i + 1
If Staff6 <> "" Then
Rng.FormulaR1C1 = "5"
i = i + 1
If Staff7 <> "" Then
Rng.FormulaR1C1 = "6"
i = i + 1
Else
Stop
End If
Wend
End Sub
Thanks in advance!
Thanks for everyone's patience. I had mad HUGE errors in writing this first code, but have fixed them thanks to your help and some of my own trial and error. The correct code is as follows. I'm sure now you'll be able to see what I was trying to do!
Sub StaffingNumbers()
Dim Rng As Range
Dim i As Long
Dim Staff1 As Range
Dim Staff2 As Range
Dim Staff3 As Range
Dim Staff4 As Range
Dim Staff5 As Range
Dim Staff6 As Range
Dim Staff7 As Range
Dim Staff8 As Range
Dim Staff9 As Range
Dim Staff10 As Range
i = 3
While i <= 300
Set Rng = Range("J" & i)
Set Staff1 = Range("X" & i)
Set Staff2 = Range("AD" & i)
Set Staff3 = Range("AJ" & i)
Set Staff4 = Range("AP" & i)
Set Staff5 = Range("AV" & i)
Set Staff6 = Range("BB" & i)
Set Staff7 = Range("BH" & i)
Set Staff8 = Range("BN" & i)
If Staff1 = "" Then
Rng.FormulaR1C1 = "0"
i = i + 1
ElseIf Staff1 <> "" And Staff2 = "" Then
Rng.FormulaR1C1 = "1"
i = i + 1
ElseIf Staff2 <> "" And Staff3 = "" Then
Rng.FormulaR1C1 = "2"
i = i + 1
ElseIf Staff3 <> "" And Staff4 = "" Then
Rng.FormulaR1C1 = "3"
i = i + 1
ElseIf Staff4 <> "" And Staff5 = "" Then
Rng.FormulaR1C1 = "4"
i = i + 1
ElseIf Staff5 <> "" And Staff6 = "" Then
Rng.FormulaR1C1 = "5"
i = i + 1
ElseIf Staff6 <> "" And Staff7 = "" Then
Rng.FormulaR1C1 = "6"
i = i + 1
ElseIf Staff7 <> "" And Staff8 = "" Then
Rng.FormulaR1C1 = "7"
i = i + 1
ElseIf Staff8 <> "" Then
Rng.FormulaR1C1 = "8"
i = i + 1
Else
Stop
End If
Wend
Set Rng = Nothing
Set Staff1 = Nothing
Set Staff2 = Nothing
Set Staff3 = Nothing
Set Staff4 = Nothing
Set Staff5 = Nothing
Set Staff6 = Nothing
Set Staff7 = Nothing
End Sub
You missed the Range in that line, first line with set Set Rng = Range("J" & i) is correct, all the others should be similar too.
The logic of what you want to accomplish after the range assignments is not clear. Perhaps this is what you hope to chieve.
Dim i As Long
Dim Staff1 As Range, Staff2 As Range, Staff3 As Range
Dim Staff4 As Range, Staff5 As Range, Staff6 As Range
Dim Staff7 As Range, Rng As Range
While i <= 300
Set Rng = Range("J" & i)
Set Staff1 = Range("X" & i)
Set Staff2 = Range("AD" & i)
Set Staff3 = Range("AJ" & i)
Set Staff4 = Range("AP" & i)
Set Staff5 = Range("BB" & i)
Set Staff6 = Range("BH" & i)
Set Staff7 = v("BN" & i)
If Staff1 <> "" Then
Rng.FormulaR1C1 = "0"
i = i + 1
ElseIf Staff2 <> "" Then
Rng.FormulaR1C1 = "1"
i = i + 1
ElseIf Staff3 <> "" Then
Rng.FormulaR1C1 = "2"
i = i + 1
ElseIf Staff4 <> "" Then
Rng.FormulaR1C1 = "3"
i = i + 1
ElseIf Staff5 <> "" Then
Rng.FormulaR1C1 = "4"
i = i + 1
ElseIf Staff6 <> "" Then
Rng.FormulaR1C1 = "5"
i = i + 1
ElseIf Staff7 <> "" Then
Rng.FormulaR1C1 = "6"
i = i + 1
Else
Stop
End If
Wend
It really isn't clear why the Stop statement is there. Perhaps you want to exit the Do While? That would be Exit Do.
You forgot to add Range in Set Staff2 = Range("AD" & i) which should be Set Staff2 = Range("AD" & i)
Also, don't forget to free your objects at the end of the proc, by using Set Staff2 = Nothing
You also forgot to close most of your If statements with End If, I let it as it was because I don't know what you want to do with your code :
Sub Staffing()
Dim Ws As Worksheet
Dim Rng As Range
Dim i As Long
Dim Staff1 As Range
Dim Staff2 As Range
Dim Staff3 As Range
Dim Staff4 As Range
Dim Staff5 As Range
Dim Staff6 As Range
Dim Staff7 As Range
i = 1
Set Ws = ThisWorkbook.Sheets("SheetNameHere")
While i <= 300
With Ws
Set Rng = .Range("J" & i)
Set Staff1 = .Range("X" & i)
Set Staff2 = .Range("AD" & i)
Set Staff3 = .Range("AJ" & i)
Set Staff4 = .Range("AP" & i)
Set Staff5 = .Range("BB" & i)
Set Staff6 = .Range("BH" & i)
Set Staff7 = .Range("BN" & i)
End With
If Staff1.Value <> "" Then
Rng.FormulaR1C1 = "0"
i = i + 1
If Staff2 <> "" Then
Rng.FormulaR1C1 = "1"
i = i + 1
If Staff3 <> "" Then
Rng.FormulaR1C1 = "2"
i = i + 1
If Staff4 <> "" Then
Rng.FormulaR1C1 = "3"
i = i + 1
If Staff5 <> "" Then
Rng.FormulaR1C1 = "4"
i = i + 1
If Staff6 <> "" Then
Rng.FormulaR1C1 = "5"
i = i + 1
If Staff7 <> "" Then
Rng.FormulaR1C1 = "6"
i = i + 1
Else
Stop
End If
Wend
Set Ws = Nothing
Set Rng = Nothing
Set Staff1 = Nothing
Set Staff2 = Nothing
Set Staff3 = Nothing
Set Staff4 = Nothing
Set Staff5 = Nothing
Set Staff6 = Nothing
Set Staff7 = Nothing
End Sub