Excel VBA - Automation Error during loop - vba

Hello there fellow StackOverflow users,
So my issue is with a workbook that heavily uses VBA to automate and calculate several functions. However the one in particular is a function I wrote that updates the code and named ranges of the workbook when the master copy is updated, which is done simply by a version number in a cell check.
Function updateCheck(cVer As Double) As Double
Dim currWB As Workbook, isWB As Workbook, iSht As Worksheet, ver As Range, wbName As String, path As String
Dim isCode As CodeModule, wbCode As CodeModule, wbMod As CodeModule, isMod As CodeModule, isNames As New Collection, isVal As New Collection
Dim tmp As Name, nm As Name, ws As Worksheet, tn As Range, verNum As Double, nStr As String, raf As Boolean, tStr As String
path = "Q:\JWILDE\": wbName = "testsheet.xlsm"
Set currWB = ThisWorkbook
With currWB
.Activate
Set wbCode = .VBProject.VBComponents("ThisWorkbook").CodeModule
Set iSht = .Sheets(1)
End With
If Dir(path & wbName) <> "" And Not currWB.path & "\" Like path Then
Set isWB = Workbooks.Open(path & wbName, ReadOnly:=True)
isWB.Activate
verNum = isWB.Names("VerNum").RefersToRange
Else
updateCheck = cVer
Exit Function
End If
If cVer < verNum Then
Debug.Print "...update required, current version: " & verNum
With isWB
With .VBProject
Set isMod = .VBComponents("ISCode").CodeModule
Set isCode = .VBComponents("ThisWorkbook").CodeModule
End With
'--- COMPILES LIST OF NAMES FROM STANDARD SHEET ---
For Each nm In .Names
nVal = "=SHT!"
key = getNRVal(nm.Name, 3)
nStr = getNRVal(nm.RefersToLocal, 3)
Debug.Print "Sheet set to: " & getNRVal(nm.Name, 1)
.Sheets(getNRVal(nm.Name, 1)).Unprotect Password:="jwedit"
Set tn = .Sheets(getNRVal(nm.Name, 1)).Range(nStr) 'Untested...
On Error Resume Next
tStr = isNames(key)
If tStr <> "" Then
tStr = ""
Else
If nm.Parent.Name = .Name Then
Set tn = .Sheets(1).Range(nStr)
nVal = "=WB!"
isVal.Add tn, key
Debug.Print "isVal > " & isVal(key).Name
End If
isNames.Add key & nVal & nStr, key
Debug.Print "...added: " & isNames.Item(key)
End If
Next nm
End With
If isCode.CountOfLines > 0 And isMod.CountOfLines > 0 Then
With currWB.VBProject
Set wbCode = .VBComponents("ISCode").CodeModule
wbCode.DeleteLines 1, wbCode.CountOfLines
wbCode.AddFromString isMod.Lines(1, isMod.CountOfLines)
Set wbCode = .VBComponents("ThisWorkBook").CodeModule
wbCode.DeleteLines 1, wbCode.CountOfLines
wbCode.AddFromString isCode.Lines(1, isCode.CountOfLines)
updateCheck = verNum
End With
Else
Debug.Print "Error. Unable to get updated code."
updateCheck = cVer
End If
isWB.Close SaveChanges:=False
currWB.Activate
On Error Resume Next
Dim wbStr As String: wbStr = isWB.Name
If wbStr <> "" Then
Debug.Print "WARNING: " & wbStr & " is still open!"
Else: Debug.Print "Successfully closed isWB."
End If
'--- CHECKS THROUGH EACH SHEET FROM CURRENT WB ---
For Each ws In currWB.Worksheets
ws.Unprotect Password:="jwedit"
'--- CHECK TO REMOVE INVALID OR INCORRECT NAMES ---
For Each nm In ws.Names
raf = False
key = getNRVal(nm.Name, 3) '--> SHEET!NAME > NAME
nStr = getNRVal(nm.RefersTo, 3) '---> SHEET!REF > REF
tStr = isNames(key) 'Could change this to: getNRVal(isNames(key),3) to return just REF or nothing.
Debug.Print "...[" & key & "]..."
If tStr <> "" Then 'MATCH FOUND...
Set tn = ws.Range(getNRVal(tStr, 3)) 'Should be the CORRECT RefTo from isNames.
'--- NAME ON WRONG SHEET ---
If ws.Index > 1 And getNRVal(tStr, 2) Like "WB" Then
Debug.Print " > REMOVE: [" & key & "] does not belong on " & ws.Name
nm.Delete
'--- NAME CORRECT BUT REFTO ISNT ---
ElseIf Not nStr Like getNRVal(tStr, 3) Then
Debug.Print " > INCORRECT: REF (" & nStr & ") of [" & key & "] should be (" & tn.Address & ")."
nm.RefersTo = tn
End If
tStr = ""
Else '--- NO MATCH FOUND / INVALID NAME ---
Debug.Print " > REMOVE: [" & key & "] is invalid."
raf = True
End If
If raf = True Then
Set tn = ws.Range(nStr)
tn.ClearContents
nm.Delete
End If
Next nm
'--- CHECKING FOR NAMES TO ADD ---
For n = 1 To isNames.Count
raf = False
key = getNRVal(isNames(n), 1) '--> NAME
nStr = getNRVal(isNames(n), 3) '--> REF
nVal = getNRVal(isNames(n), 2) '--> SHT/WB
Debug.Print "Looking for [" & key & "] on " & ws.Name
If ws.Index = 1 And nVal Like "WB" Then
tStr = currWB.Names(key, RefersTo:=nStr)
If tStr <> "" Then
tStr = ""
Else: raf = True
End If
ElseIf ws.Index > 1 And nVal Like "SHT" Then
tStr = ws.Names(key, RefersTo:=nStr)
If tStr <> "" Then
tStr = ""
Else: raf = True
End If
End If
If raf = True Then
Set tn = ws.Range(nStr)
ws.Names.Add key, tn
tStr = isVal(key).Name
If tStr <> "" Then
ws.Names.Add key, tn
tn.Value = isVal(key).Value
End If
Debug.Print " > ADDED: [" & ws.Names(key).Name & "] with REF [" & ws.Names(key).RefersToLocal & "] on " & ws.Name
End If
Next n
ws.Protect Password:="jwedit", UserInterfaceOnly:=True, AllowFormattingCells:=False
Next ws
Debug.Print " --- DONE CHECKING NAMES --- "
iSht.Activate
updateCheck = verNum
isWB.Close SaveChanges:=False
Else
Debug.Print "No update needed."
updateCheck = verNum
End If
End Function
Did my best to make it all readable, and sorry if its a bit messy. I think I have narrowed down the problem to do with protecting/unprotecting the sheets within the For Each ws in currWB.Worksheets loop as when even when I comment out the other loops for adding/removing names it still causes an Automation Error and then Excel crashes. I should also mention that every sheet only has a select cells that are editable/unprotected to try and avoid unwanted editing and format changing, which is why I need to unprotect before adding/removing names or changing cell values it seems.
Any help on this would be appreciated, or even comments if you feel I could do this any better.
Thank you!

I remember having this error and it was to do with how I was protecting the sheet for a finish I used -
For Each ws In ActiveWorkbook.Worksheets
If ws.ProtectContents = True Then
ws.Unprotect "password"
End If
Next ws
and this
For Each ws In ActiveWorkbook.Worksheets
ws.Protect "password", DrawingObjects:=True, Contents:=True, _
AllowSorting:=True, AllowFiltering:=True
Next ws
to protect

OK - I think...problem solved or found or both. Although the answer above did help thank you.
Seems the problem was down to possibly having code in the worksheet_activate and worksheet_change function, which may well have caused some continuous loop when iterating through the sheets. This was resolved simply by using Application.EnableEvents = False before the Function above is called as I don't intend any other functions/subs to be run when looping through sheets like this.

Related

Check which worksheets to export as pdf

I am a beginner in Excel VBA but I would like to create a file where I can select certain worksheets by means of a userform with checkboxes. In principle, it is then intended that only the check boxes where the value is true should be exported.
Below I have 2 codes that work well separately from each other but I have not yet been able to get them to work together.
Note: both codes come from the internet.
If possible I would like to write a loop to keep the overview.
the code to export sheets as pdf and put them in a outlook
Sub Saveaspdfandsend1()
Dim xSht As Worksheet
Dim xFileDlg As FileDialog
Dim xFolder As String
Dim xYesorNo, I, xNum As Integer
Dim xOutlookObj As Object
Dim xEmailObj As Object
Dim xUsedRng As Range
Dim xArrShetts As Variant
Dim xPDFNameAddress As String
Dim xStr As String
xArrShetts = Array("test", "Sheet1", "Sheet2") 'Enter the sheet names you will send as pdf files enclosed with quotation marks and separate them with comma. Make sure there is no special characters such as \/:"*<>| in the file name.
For I = 0 To UBound(xArrShetts)
On Error Resume Next
Set xSht = Application.ActiveWorkbook.Worksheets(xArrShetts(I))
If xSht.Name <> xArrShetts(I) Then
MsgBox "Worksheet no found, exit operation:" & vbCrLf & vbCrLf & xArrShetts(I), vbInformation, "Kutools for Excel"
Exit Sub
End If
Next
Set xFileDlg = Application.FileDialog(msoFileDialogFolderPicker)
If xFileDlg.Show = True Then
xFolder = xFileDlg.SelectedItems(1)
Else
MsgBox "You must specify a folder to save the PDF into." & vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Must Specify Destination Folder"
Exit Sub
End If
'Check if file already exist
xYesorNo = MsgBox("If same name files exist in the destination folder, number suffix will be added to the file name automatically to distinguish the duplicates" & vbCrLf & vbCrLf & "Click Yes to continue, click No to cancel", _
vbYesNo + vbQuestion, "File Exists")
If xYesorNo <> vbYes Then Exit Sub
For I = 0 To UBound(xArrShetts)
Set xSht = Application.ActiveWorkbook.Worksheets(xArrShetts(I))
xStr = xFolder & "\" & xSht.Name & ".pdf"
xNum = 1
While Not (Dir(xStr, vbDirectory) = vbNullString)
xStr = xFolder & "\" & xSht.Name & "_" & xNum & ".pdf"
xNum = xNum + 1
Wend
Set xUsedRng = xSht.UsedRange
If Application.WorksheetFunction.CountA(xUsedRng.Cells) <> 0 Then
xSht.ExportAsFixedFormat Type:=xlTypePDF, Filename:=xStr, Quality:=xlQualityStandard
Else
End If
xArrShetts(I) = xStr
Next
'Create Outlook email
Set xOutlookObj = CreateObject("Outlook.Application")
Set xEmailObj = xOutlookObj.CreateItem(0)
With xEmailObj
.Display
.To = ""
.CC = ""
.Subject = "????"
For I = 0 To UBound(xArrShetts)
.Attachments.Add xArrShetts(I)
Next
If DisplayEmail = False Then
'.Send
End If
End With
End Sub
the other code i tried I can see which checkbox is checked unfortunately I can't rewrite it so only the checked boxes will be exported to pdf.
Private Sub CommandButton100_Click()
For i = 100 To 113
If UserForm2.Controls("CheckBox" & i).Value = True Then
a = a + 1
End If
Next i
k = 1
For i = 100 To 113
If UserForm2.Controls("CheckBox" & i).Value = True And a = 1 Then
b = UserForm2.Controls("CheckBox" & i).Caption & "."
ElseIf UserForm2.Controls("CheckBox" & i).Value = True And k <> a Then
b = b & UserForm2.Controls("CheckBox" & i).Caption & ", "
k = k + 1
ElseIf UserForm2.Controls("CheckBox" & i).Value = True And k = a Then
b = b & "and " & UserForm2.Controls("CheckBox" & i).Caption & "."
End If
Next i
MsgBox ("You have selected " & b)
End Sub
Can someone help me please I am struggling for some time now?
Please, try the next function:
Private Function sheetsArr(uF As UserForm) As Variant
Dim c As MSForms.Control, strCBX As String, arrSh
For Each c In uF.Controls
If TypeOf c Is MSForms.CheckBox Then
If c.value = True Then strCBX = strCBX & "," & c.Caption
End If
Next
sheetsArr = Split(Mid(strCBX, 2), ",") 'Mid(strCBX, 2) eliminates the first string character (",")
End Function
It will return an array composed from the ticked check boxes caption.
It can be used demonstratively, in this way:
Sub testSheetsArrFunction()
Debug.Print Join(sheetsArr(UserForm2), ",")
End Sub
The above code will return in Immediate Window a string containing the checked check boxes caption (separated by comma). It may be run from a standard module, too. Of course, the function must be copied in that module. And the form to be loaded, having some check boxes ticked.
Now, you have to change a single code line in your (working) code:
Replace:
xArrShetts = Array("test", "Sheet1", "Sheet2")
with:
xArrShetts = sheetsArr(UserForm2)
It should use the array built in the above function. Of course the function have to be copied in the module where to be called. If placed in the form code module, it can be simple called as:
xArrShetts = sheetsArr(Me)
Edited:
You should only paste the next code in the form code module and show the form:
Private Sub CommandButton1_Click()
Dim xSht As Worksheet
Dim xFileDlg As FileDialog
Dim xFolder As String
Dim xYesorNo, I, xNum As Integer
Dim xOutlookObj As Object
Dim xEmailObj As Object
Dim xUsedRng As Range
Dim xArrShetts As Variant
Dim xPDFNameAddress As String
Dim xStr As String
'xArrShetts = Array("test", "Sheet1", "Sheet2") 'Enter the sheet names you will send as pdf files enclosed with quotation marks and separate them with comma. Make sure there is no special characters such as \/:"*<>| in the file name.
xArrShetts = sheetsArr(Me)
For I = 0 To UBound(xArrShetts)
On Error Resume Next
Set xSht = Application.ActiveWorkbook.Worksheets(xArrShetts(I))
If xSht.Name <> xArrShetts(I) Then
MsgBox "Worksheet no found, exit operation:" & vbCrLf & vbCrLf & xArrShetts(I), vbInformation, "Kutools for Excel"
Exit Sub
End If
Next
Set xFileDlg = Application.FileDialog(msoFileDialogFolderPicker)
If xFileDlg.Show = True Then
xFolder = xFileDlg.SelectedItems(1)
Else
MsgBox "You must specify a folder to save the PDF into." & vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Must Specify Destination Folder"
Exit Sub
End If
'Check if file already exist
xYesorNo = MsgBox("If same name files exist in the destination folder, number suffix will be added to the file name automatically to distinguish the duplicates" & vbCrLf & vbCrLf & "Click Yes to continue, click No to cancel", _
vbYesNo + vbQuestion, "File Exists")
If xYesorNo <> vbYes Then Exit Sub
For I = 0 To UBound(xArrShetts)
Set xSht = Application.ActiveWorkbook.Worksheets(xArrShetts(I))
xStr = xFolder & "\" & xSht.Name & ".pdf"
xNum = 1
While Not (Dir(xStr, vbDirectory) = vbNullString)
xStr = xFolder & "\" & xSht.Name & "_" & xNum & ".pdf"
xNum = xNum + 1
Wend
Set xUsedRng = xSht.UsedRange
If Application.WorksheetFunction.CountA(xUsedRng.Cells) <> 0 Then
xSht.ExportAsFixedFormat Type:=xlTypePDF, Filename:=xStr, Quality:=xlQualityStandard
End If
xArrShetts(I) = xStr
Next
'Create Outlook email
Set xOutlookObj = CreateObject("Outlook.Application")
Set xEmailObj = xOutlookObj.CreateItem(0)
With xEmailObj
.Display
.To = ""
.CC = ""
.Subject = "????"
For I = 0 To UBound(xArrShetts)
.Attachments.Add xArrShetts(I)
Next
If DisplayEmail = False Then
'.Send
End If
End With
End Sub
Private Function sheetsArr(uF As UserForm) As Variant
Dim c As MSForms.Control, strCBX As String, arrSh
For Each c In uF.Controls
If TypeOf c Is MSForms.CheckBox Then
If c.Value = True Then strCBX = strCBX & "," & c.Caption
End If
Next
sheetsArr = Split(Mid(strCBX, 2), ",") 'Mid(strCBX, 2) eliminates the first string character (",")
End Function

Why does VBA doesn't reach data after Row number 65,000 when using DAO with SQL language?

I have a VBA module that receives a database object, worksheet name, and two column field names as parameters to make a SQL query into another Excel table that has over 1,000,000 rows with information. But when I was debugging I noticed that my VBA code does not return the info after the row number 65,000 (approximately). This is returning wrong info and not acting properly as expected.
So, how can I handle it in my existing code?
Here is my code:
Functions
Const diretorioSA = "C:\Users\Bosch-PC\Desktop\dbLEGENDAS_ELETROPAR\"
Const BaseEletro = "dbClientesEletropar.xlsb"
Const dbClientes = "CLIENTESLDA"
Public Function Number2Letter(ByVal ColNum As Long) As String
Dim ColumnNumber As Long
Dim ColumnLetter As String
ColumnNumber = ColNum
ColumnLetter = Split(Cells(1, ColumnNumber).Address, "$")(1)
Number2Letter = ColumnLetter
End Function
Public Function GetWorkbook(ByVal sFullName As String) As Workbook
Dim sFile As String
Dim wbReturn As Workbook
sFile = DIR(sFullName)
On Error Resume Next
Set wbReturn = Workbooks(sFile)
If wbReturn Is Nothing Then
Set wbReturn = Workbooks.Open(sFullName)
End If
On Error GoTo 0
Set GetWorkbook = wbReturn
End Function
Public Function ReplaceChars(ByVal str As String, ByVal Lista As String) As String
Dim buff(), buffChars() As String
ReDim buff(Len(str) - 1): ReDim buffChars(Len(Lista) - 1)
For i = 1 To Len(str): buff(i - 1) = Mid$(str, i, 1): Next
For i = 1 To Len(Lista): buffChars(i - 1) = Mid$(Lista, i, 1): Next
For strEle = 0 To UBound(buff)
For listaEle = 0 To UBound(buffChars)
If buff(strEle) = buffChars(listaEle) Then
buff(strEle) = ""
End If
Next listaEle
novoTexto = novoTexto & buff(strEle)
Next strEle
ReplaceChars = novoTexto
End Function
Function ConsultaBaseDeDadosELETRO(ByVal CAMPO_PESQUISA As String, _
ByVal CAMPO_RETORNO As String, _
ByVal NOME_PLANILHA As String, _
ByRef BASES As Object, _
ByVal ARGUMENTO As String) As String
On Error GoTo ERRO:
Debug.Print BASES.Name
Dim RSt22 As Recordset
Set RSt22 = BASES.OpenRecordset("SELECT [" & CAMPO_RETORNO & "] FROM [" & NOME_PLANILHA & "$] WHERE [" & CAMPO_PESQUISA & "] IN ('" & ARGUMENTO & "') ;", dbOpenForwardOnly, dbReadOnly)
Debug.Print RSt22.CacheSize & " | CONTAGEM: " & RSt22.RecordCount
ConsultaBaseDeDadosELETRO = RSt22(CAMPO_RETORNO)
Exit Function
ERRO:
Debug.Print VBA.Err.Description & " | Error number: " & VBA.Err.Number & " | " & VBA.Err.HelpFile
ConsultaBaseDeDadosELETRO = "Sem registros"
End Function
Main Subroutine
Sub ProcurarBaseEletro(ByVal PASTA As String, ByVal ARQUIVO As String, ByVal NOME_PLANILHA As String, ByVal CAMPO As String)
If ActiveCell.value = "CGC" Or ActiveCell.value = "CNPJ" Or ActiveCell.value = "cgc" Or ActiveCell.value = "cnpj" Then
Application.ScreenUpdating = False
Dim wks As Worksheet: Set wks = ActiveSheet
Dim db2 As database
Dim CellRow As Single
Dim Cellcol_info, CellCol As String
Dim DiretorioBase As String: DiretorioBase = diretorioSA & BaseEletro
Dim wb As Workbook: Set wb = GetWorkbook(DiretorioBase)
If wb Is Nothing Then
MsgBox "Base de dados não localizada!" & vbNewLine & "EM: " & DiretorioBase, vbCritical, "Atenção"
Set wb = Nothing
Set wks = Nothing
Application.ScreenUpdating = True
Exit Sub
Else
wks.Activate
CellRow = ActiveCell.row
CellCol = Number2Letter(ActiveCell.Column)
Cellcol_info = Number2Letter(ActiveCell.Column + 1)
CELLCOL_LROW = ActiveSheet.Cells(ActiveSheet.Rows.Count, CellCol).End(xlUp).row
Set db2 = OpenDatabase(DiretorioBase, False, False, "Excel 8.0")
Columns(Cellcol_info & ":" & Cellcol_info).Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Range(Cellcol_info & CellRow).value = CAMPO
Dim Query As String
Dim CelAtivaValue As String
For i = CellRow + 1 To CELLCOL_LROW
CelAtivaValue = UCase(Cells(i, CellCol).value)
Query = ReplaceChars(CelAtivaValue, "/.- ")
If Left(Query, 6) < 132714 Then
Cells(i, Cellcol_info).value = ConsultaBaseDeDadosELETRO("CGC", CAMPO, NOME_PLANILHA, db2, Query)
Else
Cells(i, Cellcol_info).value = ConsultaBaseDeDadosELETRO("CGC", CAMPO, NOME_PLANILHA & 2, db2, Query)
End If
Next i
wb.Close
End If
Else
MsgBox "Texto da Célula ativa não é CGC/CNPJ, impossível fazer pesquisa", vbCritical, "Valor célula ativa: " & ActiveCell.value
Application.ScreenUpdating = True
Exit Sub
End If
Cells.EntireColumn.AutoFit
MsgBox "Processo concluído com sucesso.", vbOKOnly, "Informativo do sistema"
Application.ScreenUpdating = True
End Sub
Older Excel formats (.xls) maintains a worksheet limit of 2^16 (65536) rows. Current Excel formats (.xlsx) maintains a worksheet limit of 2^20 (1,048,576) rows.
Likely, you have a more recent version of MS Office (2007+) (given the .xlsb in BaseEletro) but your DAO code was not updated. Consider adjusting the DAO.OpenDatabase option to the newer current format.
From
Set db2 = OpenDatabase(DiretorioBase, False, False, "Excel 8.0")
To
Set db2 = OpenDatabase(DiretorioBase, False, False, "Excel 12.0 Xml")

Sharepoint version history in document via vba?

Here is my problem:
Duplicate versions
I checked the version history on the Sharepoint site and it doesn't show any duplicates.
Here is the code im using:
Sub versionhistory()
'
' versionhistory Macro
On Error Resume Next
' On Error GoTo message
Dim dlvVersions As Office.DocumentLibraryVersions
Dim dlvVersion As Office.DocumentLibraryVersion
Dim strVersionInfo As String
Set dlvVersions = ThisDocument.DocumentLibraryVersions
'MsgBox ActiveDocument.Bookmarks.Count
Dim tbl As Word.Table
'Set tbl = ActiveDocument.Tables.Item(2)
Set tbl = ActiveDocument.Bookmarks("VersionTable").Range.Tables(1)
If dlvVersions.IsVersioningEnabled Then
strVersionInfo = "This document has " & dlvVersions.Count & " versions: " & vbCrLf
Call InsertVersionHistory(tbl, dlvVersions)
For Each dlvVersion In dlvVersions
strVersionInfo = strVersionInfo & _
" - Version #: " & dlvVersion.Index & vbCrLf & _
" - Modified by: " & dlvVersion.ModifiedBy & vbCrLf & _
" - Modified on: " & dlvVersion.Modified & vbCrLf & _
" - Comments: " & dlvVersion.Comments & vbCrLf
Next
Else
strVersionInfo = "Versioning not enabled for this document."
End If
'MsgBox strVersionInfo, vbInformation + vbOKOnly, "Version Information"
Set dlvVersion = Nothing
Set dlvVersions = Nothing
Call GetUserName
'message:
'MsgBox Err.Description
MsgBox ("Insert Version Number in the Header and type a Title in the [Insert Title here] on the front page. It will be automatically updated in the footer." & vbNewLine & vbNewLine & "Do Not Type in the Review and Version tables.")
End Sub
Private Function InsertVersionHistory(oVerTbl As Word.Table, oVersions As Office.DocumentLibraryVersions)
Dim rowIndex As Integer
Dim oVersion As Office.DocumentLibraryVersion
Dim oNewRow As Row
'test
Dim versionIndex As Integer
For rowIndex = 2 To oVerTbl.Rows.Count
oVerTbl.Rows.Item(2).Delete
Next rowIndex
rowIndex = 1
'test
versionIndex = oVersions.Count
For Each oVersion In oVersions
If (rowIndex > 5) Then
Return
End If
rowIndex = rowIndex + 1
oVerTbl.Rows.Add
Set oNewRow = oVerTbl.Rows(oVerTbl.Rows.Count)
oNewRow.Shading.BackgroundPatternColor = wdColorWhite
oNewRow.Range.Font.TextColor = wdBlack
oNewRow.Range.Font.Name = "Tahoma"
oNewRow.Range.Font.Bold = False
oNewRow.Range.Font.Size = 12
oNewRow.Range.ParagraphFormat.SpaceAfter = 4
With oNewRow.Cells(1)
'.Range.Text = oVersion.Index
.Range.Text = versionIndex
End With
With oNewRow.Cells(2)
.Range.Text = FormUserFullName(GetUserFullName(oVersion.ModifiedBy))
End With
With oNewRow.Cells(3)
.Range.Text = oVersion.Modified
End With
With oNewRow.Cells(4)
.Range.Text = oVersion.Comments
End With
versionIndex = versionIndex - 1
Next
Set oVersion = Nothing
End Function
Function GetUserFullName(userName As String) As String
Dim WSHnet, UserDomain, objUser
Set WSHnet = CreateObject("WScript.Network")
'UserDomain = WSHnet.UserDomain
'Set objUser = GetObject("WinNT://" & UserDomain & "/" & userName & ",user")
userName = Replace(userName, "\", "/")
Set objUser = GetObject("WinNT://" & userName & ",user")
'MsgBox objUser.FullName
GetUserFullName = objUser.FullName
End Function
Function FormUserFullName(userName As String) As String
Dim arrUserName As Variant
Dim changedUserName As String
arrUserName = Split(userName, ",")
Dim length As Integer
length = UBound(arrUserName) - LBound(arrUserName) + 1
If length >= 2 Then
changedUserName = arrUserName(1) & " " & arrUserName(0)
Else
changedUserName = userName
End If
FormUserFullName = changedUserName
End Function
Private Function GetUserName()
Dim userName As String
userName = ActiveDocument.BuiltInDocumentProperties("Author")
ActiveDocument.BuiltInDocumentProperties("Author") = FormUserFullName(userName)
End Function
I know this is old, but I was looking for the same thing and found this article. I'm still trying it out, but wanted to share before I got distracted with my real job.
From: SixSigmaGuy on microsoft.public.sharepoint.development-and-programming.narkive.com/...
Wanted to share my findings, so far. Surprisingly, I could not find
anything in the SharePoint Designer object/class that supported versions,
but the Office, Word, Excel, and PowerPoint objects do support it.. It
wasn't easy to find, but once I found it, it works great, as long as the
file in the document library is one of the Office documents.
Here's some sample code, written in Excel VBA, showing how to get the
version information for a paritcular SharePoint Document Library file
created in Excel:
Public viRow As Long
Function fCheckVersions(stFilename As String) As Boolean
' stFilename is the full URL to a document in a Document Library.
'
Dim wb As Excel.Workbook
Dim dlvVersions As Office.DocumentLibraryVersions
Dim dlvVersion As Office.DocumentLibraryVersion
Dim stExtension As String
Dim iPosExt As Long
ThisWorkbook.Worksheets("Sheet1").Cells(viRow, 1) = stFilename
If Workbooks.CanCheckOut(stFilename) = True Then
Set wb = Workbooks.Open(stFilename, , True)
Set dlvVersions = wb.DocumentLibraryVersions
If dlvVersions.IsVersioningEnabled = True Then
ThisWorkbook.Worksheets("Sheet1").Cells(viRow, 3) = "Num
Versions = " & dlvVersions.Count
For Each dlvVersion In dlvVersions
ThisWorkbook.Worksheets("Sheet1").Cells(viRow, 4) = "Version: " & dlvVersion.Index
ThisWorkbook.Worksheets("Sheet1").Cells(viRow, 5) = "Modified Date: " & dlvVersion.Modified
ThisWorkbook.Worksheets("Sheet1").Cells(viRow, 6) = "Modified by: " & dlvVersion.ModifiedBy
ThisWorkbook.Worksheets("Sheet1").Cells(viRow, 7) = "Comments: " & dlvVersion.Comments
viRow = viRow + 1
Next dlvVersion
End If
wb.Close False
End If
Set wb = Nothing
DoEvents
End Function`
Fortunately, I discovered that Excel can open non-Excel files in most
cases. I.e., I can, for example, open a jpg file in Excel and use the
dlvVersions collection for that file.

sub or function not defined copy pasting from one file to another

I have the following code to copy yearly precipitation data from 132 different excel files to one large dataset. I have precipitation data from multiple different sites which I am placing in different columns hence the different col values. I also want to match the dates hence the rw value. However, I am getting that my sub is not defined and I am not sure why.
Sub f()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim directory As String, fileName As String
directory = "C:\Working-Directory\Precipdata"
fileName = Dir(directory & "*.csv")
Do While fileName <> ""
Workbooks.Open (directory & fileName)
With (Workbooks(directory & fileName))
If Range("B2").Value = "GJOA HAVEN A" Then col = "B & rw :D & rw+lngth-27"
If Range("B2").Value = "TALOYOAK A" Then col = "E & rw :G & rw+lngth-27"
If Range("B2").Value = "GJOA HAVEN CLIMATE" Then col = "H & rw :J & rw+lngth-27"
If Range("B2").Value = "HAT ISLAND" Then col = " & rw :M & rw+lngth-27"
If Range("B2").Value = "BACK RIVER (AUT)" Then col = "N & rw :P & rw+lngth-27"
yr = Range("B27").Value
lngth = (Range("B27").End(xlDown).Row)
End With
Workbook(Macroforprecip.xlsm).Activate
rw = Cells.Find("01/01/" & yr).Row
Workbooks(fileName).Range("P&R&T" & (Range("B27").End(xlDown).Row)).Copy_Workbooks(Macroforprecip.xlsm).Range (col)
Workbooks(fileName).Close
fileName = Dir()
Loop
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Also I really wanted to use the cells function so I could make col a numeric value and just add two but I can't find how to do the equivalent of Range(""A"& i : "G" & i") with it.
OK so I updated it to be slightly more simple. I am only copying one column at a time and I did change the workbook() function to workbooks() my new code looks like this.
Sub precipitation()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim directory As String, fileName As String
directory = "C:\Working-Directory\Precipdata\"
fileName = Dir(directory & "*.csv")
Do While fileName <> ""
sheetName = Left(fileName, Len(fileName) - 4)
Workbooks.Open (directory & fileName)
Workbooks(fileName).Activate
If Range("B1").Value = "GJOA HAVEN A" Then
col = "B"
End If
If Range("B1").Value = "TALOYOAK A" Then
col = "E"
End If
If Range("B1").Value = "GJOA HAVEN CLIMATE" Then
col = "H"
End If
If Range("B1").Value = "HAT ISLAND" Then
col = "K"
End If
If Range("B1").Value = "BACK RIVER (AUT)" Then
col = "N"
End If
yr = Range("B27").Value
lngth = (Range("B27").End(xlDown).Row)
Workbooks("Macroforprecip.xlsm").Activate
Set rw = ActiveSheet.Cells.Find(what:=DateValue("01/01/" & yr))
r = rw.Row
Workbooks(fileName).Range("P27", "P" & lngth).Copy_Workbooks("Macroforprecip.xlsm").Range (col & r)
Workbooks(fileName).Close
fileName = Dir()
Loop
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
My new error is that I get "Run-time error '438':
Object doesn't support this property or method."
This happens at the Line that actually does the copying over `
(Workbooks(fileName).Range("P27", "P" & lngth).Copy_Workbooks("Macroforprecip.xlsm").Range (col & r)`
I do not fully understand what this means and even more so I do not understand what to do about it. Thank you all for the help so far.
This line fails:
Workbook(Macroforprecip.xlsm).Activate
because there's no function called Workbook. You probably meant to use the application workbooks collection, like this:
Workbooks("Macroforprecip.xlsm").Activate
I made a lot of changes because there were a lot of problems. See if this gets you a little closer:
Sub f()
Dim wb As Workbook ' define workbook object
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim directory As String, fileName As String
directory = "C:\Working-Directory\Precipdata\" ' added backslash
fileName = Dir(directory & "*.csv")
Do While fileName <> ""
Set wb = Workbooks.Open(directory & fileName) ' set a workbook object
With wb ' use workbook object instead
If Range("B2").Value = "GJOA HAVEN A" Then col = "B" & rw & ":D" & rw + lngth - 27 ' fixed
If Range("B2").Value = "TALOYOAK A" Then col = "E" & rw & ":G" & rw + lngth - 27 ' fixed
If Range("B2").Value = "GJOA HAVEN CLIMATE" Then col = "H" & rw & ":J" & rw + lngth - 27 ' fixed
'If Range("B2").Value = "HAT ISLAND" Then col = " & rw :M & rw+lngth-27" ' missing column so removed
If Range("B2").Value = "BACK RIVER (AUT)" Then col = "N" & rw & ":P" & rw + lngth - 27
yr = Range("B27").Value
lngth = (Range("B27").End(xlDown).Row)
.Activate
'Workbook(Macroforprecip.xlsm).Activate ' moved into the With
rw = Cells.Find("01/01/" & yr).Row
wb.Range("P&R&T" & (Range("B27").End(xlDown).Row)).Copy wb.Range(col) ' not sure what you are trying to do here
End With
wb.Close
fileName = Dir()
Loop
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub

copy files from source folder to target based on excel list

I am using this to try and copy photos that exist in the list within a list in excel. it seems check but doesn't see anything in the source folder and returns the "Does N" from the code below. I have enabled macros and the folders don't see locked. any help would be much appriciated
Option Explicit
Sub CopyFiles()
Dim iRow As Integer ' ROW COUNTER.
Dim sSourcePath As String
Dim sDestinationPath As String
Dim sFileType As String
Dim bContinue As Boolean
bContinue = True
iRow = 1
' THE SOURCE AND DESTINATION FOLDER WITH PATH.
sSourcePath = "C:\Users\username\Desktop\source\"
sDestinationPath = "C:\Users\username\Desktop\TARGET\"
sFileType = ".jpg" ' TRY WITH OTHER FILE TYPES LIKE ".pdf".
' LOOP THROUGH COLUMN "A" TO PICK THE FILES.
While bContinue
If Len(Range("A" & CStr(iRow)).Value) = 0 Then ' DO NOTHING IF THE COLUMN IS BLANK.
MsgBox "Process executed" ' DONE.
bContinue = False
Else
' CHECK IF FILES EXISTS.
If Len(Dir(sSourcePath & Range("A" & CStr(iRow)).Value & sFileType)) = 0 Then
Range("B" & CStr(iRow)).Value = "Does N"
Range("B" & CStr(iRow)).Font.Bold = True
Else
Range("B" & CStr(iRow)).Value = "On Hand"
Range("B" & CStr(iRow)).Font.Bold = False
If Trim(sDestinationPath) <> "" Then
Dim objFSO
Set objFSO = CreateObject("scripting.filesystemobject")
' CHECK IF DESTINATION FOLDER EXISTS.
If objFSO.FolderExists(sDestinationPath) = False Then
MsgBox sDestinationPath & " Does Not Exists"
Exit Sub
End If
'*****
' HERE I HAVE INCLUDED TWO DIFFERENT METHODS.
' I HAVE COMMENTED THE SECOND METHOD. TO THE SEE THE RESULT OF THE
' SECOND METHOD, UNCOMMENT IT AND COMMENT THE FIRST METHOD.
' METHOD 1) - USING "CopyFile" METHOD TO COPY THE FILES.
objFSO.CopyFile Source:=sSourcePath & Range("A" & CStr(iRow)).Value & _
sFileType, Destination:=sDestinationPath
' METHOD 2) - USING "MoveFile" METHOD TO PERMANENTLY MOVE THE FILES.
'objFSO.MoveFile Source:=sSourcePath & Range("A" & CStr(iRow)).Value & _
sFileType, Destination:=sDestinationPath
'*****
End If
End If
End If
iRow = iRow + 1 ' INCREMENT ROW COUNTER.
Wend
End Sub
You shouldn’t be creating a new FileSystemObject on every iteration. Also, the destination folder can only be checked once - no need to check it every time.
See below your code with a few changes.
Option Explicit
Sub CopyFiles()
On Error GoTo Errproc
Const sSourcePath As String = "C:\Users\username\Desktop\source\"
Const sDestinationPath As String = "C:\Users\username\Desktop\TARGET\"
Const sFileType As String = ".jpg"
'validate destination folder
If Len(Dir(sDestinationPath)) = 0 Then
MsgBox "Destination path does not exist..."
Exit Sub
End If
Dim iRow As Integer
iRow = Range("A" & Rows.Count).End(xlUp).Row
Dim rr As Range, r As Range
Set rr = Range("A1:A" & iRow)
Dim objFSO As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
For Each r In rr
With objFSO
If Not .FileExists(sSourcePath & r.Value & sFileType) Then
r.Offset(0, 1).Value = "Does N"
r.Offset(0, 1).Font.Bold = True
Else
r.Offset(0, 1).Value = "On Hand"
r.Offset(0, 1).Font.Bold = False
objFSO.CopyFile sSourcePath & r.Value & sFileType, sDestinationPath, True 'Overwrite
'objFSO.MoveFile Source:=sSourcePath & r.Value & sFileType , Destination:=sDestinationPath
End If
End With
Next r
Leave:
Set objFSO = Nothing
On Error GoTo 0
Exit Sub
Errproc:
MsgBox Err.Description, vbCritical
Resume Leave
End Sub