Is possible to popolate one pubblic collection from one external file?!?!?
I can't show the collection items,
to test this code I tried to loop the collection's item then
if the loop is before close the wb source, the result show right
but if I close che wb source I can only count the items collection.item = 31 (right result) if I try debug.print collection(x) 'x are integer from 1 to 31
I retrieve only Error 424.
Is my code, wrong, or is not possible to polulate one collection from an external file and, in this case what I've to use?!?!
Below my code:
option explicit
public Belts as collection
Public Sub mCaricaBelts()
On Error GoTo RigaErrore
Dim wb As Workbook, wbn As String
Dim sh As Worksheet
Dim rng As Range
Dim c As Range, v As Variant
Dim lrw As Long
With Application
.ScreenUpdating = False
.Calculation = xlManual
.StatusBar = _
"Sto caricato la tabella Fasce"
End With
wbn = "Listino.xlsx"
If Not Belts Is Nothing Then
Set Belts = Nothing
End If
Set Belts = New Collection
If AlreadyOpen(wbn) Then
Set wb = Workbooks(wbn)
Else
Set wb = Workbooks.Open("\\itcpifs01\license$\Listino.xlsx")
End If
Set rng = wb.Worksheets("dbRatesSTD").Range("C1")
Set rng = Range(rng, rng.End(xlToRight))
For Each c In rng
Belts.Add c
Next
' if I put the loop here, I can show results
For Each v In Belts
Debug.Print v
Next
Application.DisplayAlerts = False
wb.Close
Application.DisplayAlerts = True
' if I put the loop here, I can't show results, Error 424 Object required
For Each v In Belts
Debug.Print v
Next
RigaChiusura:
Set c = Nothing
Set rng = Nothing
Set sh = Nothing
With Application
.ScreenUpdating = True
.Calculation = xlAutomatic
.StatusBar = ""
End With
Exit Sub
RigaErrore:
MsgBox Err.Number & vbNewLine & Err.Description
Resume RigaChiusura
End Sub
Try Belts.Add c.Value, which will add the value in the cell to the collection as opposed to adding a reference to the range object to the collection. The value will still be available after the workbook is closed, as opposed to the reference which will no longer be available.
Array version
Don't know much about collections but I think arrays is the way to go.
Option Explicit
Public Belts As Variant 'Public Belts As Collection
Public Sub mCaricaBelts()
On Error GoTo RigaErrore
Dim wb As Workbook, wbn As String
Dim sh As Worksheet
Dim rng As Range
Dim c As Range, v As Variant
Dim lrw As Long
With Application
.ScreenUpdating = False
.Calculation = xlManual
.StatusBar = _
"Sto caricato la tabella Fasce"
End With
wbn = "Listino.xlsx"
' If Not Belts Is Nothing Then
' Set Belts = Nothing
' End If
' Set Belts = New Collection
If AlreadyOpen(wbn) Then
Set wb = Workbooks(wbn)
Else
Set wb = Workbooks.Open("\\itcpifs01\license$\Listino.xlsx")
End If
Set rng = wb.Worksheets("dbRatesSTD").Range("C1")
Set rng = Range(rng, rng.End(xlToRight))
'Be careful, this is a horizontal array.
Belts = rng
' For Each c In rng
' Belts.Add c
' Next
' if I put the loop here, I can show results
For Each v In Belts
Debug.Print v
Next
Application.DisplayAlerts = False
wb.Close
Application.DisplayAlerts = True
' if I put the loop here, I can't show results, Error 424 Object required
For Each v In Belts
Debug.Print v
Next
RigaChiusura:
Set c = Nothing
Set rng = Nothing
Set sh = Nothing
With Application
.ScreenUpdating = True
.Calculation = xlAutomatic
.StatusBar = ""
End With
Exit Sub
RigaErrore:
MsgBox Err.Number & vbNewLine & Err.Description
Resume RigaChiusura
End Sub
I have older Excel so I can only imagine what AlreadyOpen(wbn) means, but here's the old way for the complete If statement for your code:
'Check if Excel file is opened:
On Error Resume Next
Set wb = Workbooks(wbn) 'Workbook is opened.
If Err then 'Workbook is closed.
Set wb = Workbooks.Open("\\itcpifs01\license$\Listino.xlsx")
Err.Clear
End If
On Error GoTo RigaErrore 'Reactivate your 'first line error'.
There are no constants in your code. I would add this to the beginning of the code and make appropriate changes:
Const cStrTabella as String = "Sto caricato la tabella Fasce"
Const cStrWbn as String = "Listino.xlsx"
Const cStrWbp as String = "\\itcpifs01\license$\Listino.xlsx"
Const cStrWs as String = "dbRatesSTD"
Const cStrAddress as String = "C1"
Now it's much easier to change stuff and for someone else to modify it for a test and you can much faster get an answer for a problem.
Related
I want to extract a range from values in cells in excel. with this code i get a error every time, but not when i put the row and column index numbers manually. This is the code:
Sub Checker()
With Application
.DisplayAlerts = False
.EnableEvents = False
End With
Dim folderpath As String
Dim workbookname As String
Dim filepath As String
folderpath = Range("B3").Value
workbookname = Range("B6").Value
filepath = folderpath + workbookname
Workbooks.Open Filename:=filepath
Range("A1").Select
Dim last_cell As Variant
Dim last_column As Variant
Dim last_row As Variant
last_column = Range("B12").Value
last_row = Range("E12").Value
last_cell = Range("B15").Value
Dim rng As Range, cell As Range
Set rng = Range(Cells(1, 1), Cells(last_row, last_column))
For Each cell In rng
If cell.Locked = True Then
Else
cell.Value = "N/P"
End If
Next cell
With Application
.DisplayAlerts = True
.EnableEvents = True
End With
End Sub
the last column should be "13" and the last row should be "51"
but every time I get error 1004.
the problem is in the set rng
Define your row/column variables as Long and specify a workbook and worksheet for every object that is located in a worksheet.
Option Explicit
Public Sub Checker()
With Application
.DisplayAlerts = False
.EnableEvents = False
End With
Dim folderpath As String
folderpath = ThisWorkbook.Worksheets("Sheet1").Range("B3").Value
Dim workbookname As String
workbookname = ThisWorkbook.Worksheets("Sheet1").Range("B6").Value
Dim filepath As String
filepath = folderpath & workbookname 'concatenate strings with & not +
Dim OpenedWb As Workbook ' set the opened workbook as a variable so you can reference it later
Set OpenedWb = Workbooks.Open(Filename:=filepath)
Dim ws As Worksheet ' define the worksheet you want to use in that workbook
Set ws = OpenedWb.Worksheets(1) 'select your sheet by tab position or
'Set ws = OpenedWb.Worksheets("Sheet1") 'select your sheet by tab name
Dim last_column As Long
last_column = ws.Range("B12").Value
Dim last_row As Long
last_row = ws.Range("E12").Value
Dim rng As Range,
Set rng = ws.Range(ws.Cells(1, 1), ws.Cells(last_row, last_column))
Dim cell As Range
For Each cell In rng
If Not cell.Locked = True Then
cell.Value = "N/P"
End If
Next cell
'OpenedWb.Close SaveChanges:=True 'if you want to close and save
With Application
.DisplayAlerts = True
.EnableEvents = True
End With
End Sub
Note that if you disalbe events, then make sure you use error handling to enable events in any case of error or they will be turned of until you close Excel.
For Example
Public Sub Example()
Application.EnableEvents = False
On Error Goto SAVE_EXIT
' your code here …
Application.EnableEvents = True
On Error Goto 0 ' re-enable error reporting
Exit Sub
SAVE_EXIT: ' in case of error enable events
Application.EnableEvents = True
' and show error message
If Err.Number Then
Err.Raise Err.Number
End If
End Sub
I have a client who is hand holding a bunch of worksheets that should be standardized. They are created from importing CSV files. Basically, I need to replace the current manual sheets while they are being referenced from another tab without breaking the current references.
I've reduced the problem to a single workbook with 2 sheets. Sheet1 cell A1 references Sheet2 cell A1 which holds the string "Sheet2A1CellData"
Everything commented out below has been tried including Application.Volatile and Application.Calculation.
Option Explicit
Sub TestSheet2Delete()
Dim TmpSheet2 As Worksheet: Set TmpSheet2 = Sheets("Sheet2")
'Application.Volatile
If TmpSheet2 Is Nothing Then
Exit Sub
End If
'Application.Calculation = False
Application.DisplayAlerts = False
TmpSheet2.Delete
Application.DisplayAlerts = True
Set TmpSheet2 = Worksheets.Add(After:=Sheets("Sheet1"))
If TmpSheet2 Is Nothing Then
Exit Sub
End If
TmpSheet2.Name = "Sheet2"
TmpSheet2.Range("A1").Value = "Sheet2A1CellData"
'Application.Calculation = True
End Sub
Sheet1 A1 was originally =Sheet2!A1. When I run the function above from the VBE, Sheet1 cell A1 is set to =#REF!A1.
How can I keep the reference valid after the sheet has been replaced?
Obviously, the real world problem is much larger and re-importing CSV data requires updating 132,000 cells. 6000 rows x 22 Columns.
Thanks for any help.
Thank you presenting a real good question.
First of all disclaimer: This is not an direct solution but and workaround we had to adopt years back.
Exactly similar problem problem had been encountered in my workplace (literally made us to pull out our hairs), and we also tried to go for iNDIRECT. But since the formulas in the working sheets are complex we failed to replace them with INDIRECT. So instead of lengthy manual replacement of the hundreds of Formulas in the working sheet, we used to insert a temp Sheet and change the formulas reference to that sheet. After importing new sheet and renaming it as old sheet's name, formulas were reverted back to original.
I tried to reproduce the code used (since I don't have access to same files now). We only used the Sub ChangeFormulas, Here I used the same in line with your code.
Option Explicit
Sub TestSheet2Delete()
Dim Wb As Workbook
Dim Ws As Worksheet, Ws1 As Worksheet, Ws2 As Worksheet
Dim Xstr As String, Ystr As String
Set Wb = ThisWorkbook
Set Ws = Wb.Sheets("Sheet1")
Xstr = "Sheet2"
Ystr = "TempSheetX"
Set Ws1 = Wb.Sheets(Xstr)
Set Ws2 = Worksheets.Add(After:=Ws)
Ws2.Name = Ystr
DoEvents
ChangeFormulas Ws, Xstr, Ystr
Application.DisplayAlerts = False
Ws1.Delete
' Now again add another sheet with Old name and change formulas back to Original
Set Ws1 = Worksheets.Add(After:=Ws)
Ws1.Name = Xstr
DoEvents
ChangeFormulas Ws, Ystr, Xstr
Ws2.Delete
Application.DisplayAlerts = True
End Sub
Sub ChangeFormulas(Ws As Worksheet, Xstr As String, Ystr As String)
Dim Rng As Range, C As Range, FirstAddress As String
Set Rng = Ws.UsedRange
With Rng
Set C = .Find(What:=Xstr, LookIn:=xlFormulas)
If Not C Is Nothing Then
FirstAddress = C.Address
Do
C.Formula = Replace(C.Formula, Xstr, Ystr)
Set C = .FindNext(C)
If C Is Nothing Then Exit Do
If C.Address = FirstAddress Then Exit Do
Loop
End If
End With
End Sub
Another simplest workaround is not to delete the Sheet at all and import the CSV and copy the full sheet onto the sheet in question. However This fully depends on actual working conditions involving CSV and all.
AFTER I posted (of course :-)), this link came up on the right: Preserve references that recommends using INDIRECT. I have now changed Sheet1 A1 to =INDIRECT("Sheet2!"&"A1").
I am not certain why the named ranges suggested in the link are needed. The indirect call above seems to work without a named range.
If this works in the larger project, I will mark this as complete.
My original answer did not work for non-contiguous cells. However, I really like the Range to Variants and then back to Range pattern. Very fast. So I rewrote my original answer into more reusable code that tests using non-contiguous cells.
Function PreserveFormulaeInVariantArr(ByVal aWorksheet As Worksheet, _
ByVal aIsNoFormulaErr As Boolean, _
ByRef aErrStr As String) As Variant
Dim TmpRange As Range
Dim TmpAreaCnt As Long
Dim TmpVarArr As Variant
Dim TmpAreaVarArr As Variant
PreserveFormulaeInVariantArr = Empty
If aWorksheet Is Nothing Then
aErrStr = "PreserveFormulaeInVariantArr: Worksheet is Nothing."
Exit Function
End If
Err.Clear
On Error Resume Next
Set TmpRange = aWorksheet.Cells.SpecialCells(xlCellTypeFormulas)
If Err.Number <> 0 Then 'No Formulae.
PreserveFormulaeInVariantArr = Empty
If aIsNoFormulaErr Then
aErrStr = "PreserveFormulaeInVariantArr: No cells with formulae."
End If
Exit Function
End If
TmpAreaVarArr = Empty
On Error GoTo ErrLabel
ReDim TmpVarArr(1 To TmpRange.Areas.Count, 1 To 2)
For TmpAreaCnt = LBound(TmpVarArr) To UBound(TmpVarArr)
TmpVarArr(TmpAreaCnt, 1) = TmpRange.Areas(TmpAreaCnt).Address 'Set 1st Element to Range
TmpAreaVarArr = TmpRange.Areas(TmpAreaCnt).Formula 'Left TmpArrVarArr for Debugging
TmpVarArr(TmpAreaCnt, 2) = TmpAreaVarArr 'Creates Jagged Array
Next TmpAreaCnt
PreserveFormulaeInVariantArr = TmpVarArr
Exit Function
ErrLabel:
aErrStr = "PreserveFormulaeInVariantArr - Error Number: " + CStr(Err.Number) + " Error Description: " + Err.Description
End Function
Function RestoreFormulaeFromVariantArr(ByVal aWorksheet As Worksheet, _
ByVal aIsEmptyAreaVarArrError As Boolean, _
ByVal aAreaVarArr As Variant, _
ByRef aErrStr As String) As Boolean
Dim TmpVarArrCnt As Long
Dim TmpRange As Range
Dim TmpDim1Var As Variant
Dim TmpDim2Var As Variant
Dim TmpDim2Cnt As Long
Dim TmpDim2UBound As Long
RestoreFormulaeFromVariantArr = False
On Error GoTo ErrLabel
If aWorksheet Is Nothing Then
Exit Function
End If
If IsEmpty(aAreaVarArr) Then
If aIsEmptyAreaVarArrError Then
aErrStr = "RestoreFormulaeFromVariantArr: Empty array passed."
Else
RestoreFormulaeFromVariantArr = True
End If
Exit Function
End If
For TmpVarArrCnt = 1 To UBound(aAreaVarArr)
TmpDim1Var = aAreaVarArr(TmpVarArrCnt, 1) 'This is always the range.
TmpDim2Var = aAreaVarArr(TmpVarArrCnt, 2) 'This can be a Variant or Variant Array
aWorksheet.Range(TmpDim1Var).Formula = TmpDim2Var
Next TmpVarArrCnt
RestoreFormulaeFromVariantArr = True
Exit Function
ErrLabel:
aErrStr = "PreserveFormulaeInVariantArr - Error Number: " + CStr(Err.Number) + " Error Description: " + Err.Description
End Function
Sub TestPreserveFormulaeInVariantArr()
Dim TmpPreserveFormulaeArr As Variant
Dim TmpErrStr As String
Dim TmpIsNoFormulaErr As Boolean: TmpIsNoFormulaErr = True 'Change If Desired
Dim TmpEmptySheet1 As Boolean: TmpEmptySheet1 = False 'Change If Desired
Dim TmpSheet1 As Worksheet: Set TmpSheet1 = Sheets("Sheet1")
Dim TmpSheet2 As Worksheet
Err.Clear
On Error Resume Next
Set TmpSheet2 = Sheets("Sheet2")
On Error GoTo 0
'Always Delete Sheet2
If (TmpSheet2 Is Nothing) = False Then
Application.DisplayAlerts = False
TmpSheet2.Delete
Application.DisplayAlerts = True
Set TmpSheet2 = Nothing
End If
If TmpSheet2 Is Nothing Then
Set TmpSheet2 = Worksheets.Add(After:=Sheets("Sheet1"))
TmpSheet2.Name = "Sheet2"
TmpSheet2.Range("A1") = "Sheet2A1"
TmpSheet2.Range("B1") = "Sheet2A1"
TmpSheet2.Range("C4") = "Sheet2C4"
If TmpEmptySheet1 Then
TmpSheet1.Cells.ClearContents
Else
TmpSheet1.Range("A1").Formula = "=Sheet2!A1"
TmpSheet1.Range("B1").Formula = "=Sheet2!B1"
TmpSheet1.Range("C4").Formula = "=Sheet2!C4"
End If
End If
TmpPreserveFormulaeArr = PreserveFormulaeInVariantArr(TmpSheet1, TmpIsNoFormulaErr, TmpErrStr)
If TmpErrStr <> "" Then
MsgBox TmpErrStr
Exit Sub
End If
'Break Formulae and Cause #Ref Violation
Application.DisplayAlerts = False
TmpSheet2.Delete
Application.DisplayAlerts = True
'Add Sheet2 Back
Set TmpSheet2 = Worksheets.Add(After:=Sheets("Sheet1"))
TmpSheet2.Name = "Sheet2"
TmpSheet2.Range("A1") = "Sheet2A1"
TmpSheet2.Range("B1") = "Sheet2A1"
TmpSheet2.Range("C4") = "Sheet2C4"
'Restore Formulas Back to Sheet1
If RestoreFormulaeFromVariantArr(TmpSheet1, TmpIsNoFormulaErr, TmpPreserveFormulaeArr, TmpErrStr) = False Then
MsgBox TmpErrStr
Exit Sub
End If
End Sub
The TestPreserveFormulaeInVariantArr can be run in the VBE with options to set empty values. Any comments appreciated.
I have about 100 Word documents and from each I want to copy data and paste it all in one Excel workbook.
I came up with this code which opens one Word document, copies data, pastes it to Excel and closes the Word document:
Sub WordDataToExcel()
Dim myObj
Dim myWB
Dim mySh
Dim txt As String, Lgth As Long, Strt As Long
Dim i As Long
Dim oRng As Range
Dim Tgt As String
Dim TgtFile As String
Dim arr()
Dim ArrSize As Long
Dim ArrIncrement As Long
ArrIncrement = 1000
ArrSize = ArrIncrement
ReDim arr(ArrSize)
Dim wrdDoc As Object
Documents.Open ("D:\ekr5_i.doc")
TgtFile = "result.xlsx"
Tgt = "D:\" & TgtFile
'finds the text string of Lgth lenght
txt = "thetext"
Lgth = 85
Strt = Len(txt)
'Return data to array
With Selection
.HomeKey unit:=wdStory
With .Find
.ClearFormatting
.Forward = True
.Text = txt
.Execute
While .Found
i = i + 1
Set oRng = ActiveDocument.Range _
(Start:=Selection.Range.Start + Strt, _
End:=Selection.Range.End + Lgth)
arr(i) = oRng.Text
oRng.Start = oRng.End
.Execute
If i = ArrSize - 20 Then
ArrSize = ArrSize + ArrIncrement
ReDim Preserve arr(ArrSize)
End If
Wend
End With
End With
ReDim Preserve arr(i)
'Set target and write data
Set myObj = CreateObject("Excel.Application")
Set myWB = myObj.Workbooks.Open(Tgt)
Set mySh = myWB.Sheets(1)
With mySh
.Range(.Cells(1, 1), .Cells(i, 1)) = myObj.Transpose(arr)
End With
'Tidy up
myWB.Close True
myObj.Quit
ActiveDocument.Close SaveChanges:=wdDoNotSaveChanges
Set mySh = Nothing
Set myWB = Nothing
Set myObj = Nothing
End Sub
I need to loop through all the documents in the folder.
I have implemented the same with Excel workbooks, but I don't know how for Word documents.
Here is the code for Excel workbooks:
Sub combine_into_one()
Dim FSO As Object: Set FSO = CreateObject("Scripting.FileSystemObject")
Dim strPath$, Pivot$, sUserName$, sFolderName$, sSourceName$, x&
Dim oFldialog As FileDialog
Dim oFolder
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Set oFldialog = Application.FileDialog(msoFileDialogFolderPicker)
With oFldialog
If .Show = -1 Then
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = strPath
sFolderName = .SelectedItems(1)
End If
End With
Set oFolder = FSO.GetFolder(sFolderName)
Workbooks.Add: Pivot = ActiveWorkbook.Name 'Destination workbook
For Each oFile In oFolder.Files
Workbooks(Pivot).Activate
x = Workbooks(Pivot).Sheets(1).Cells.SpecialCells(xlCellTypeLastCell).Row + 1
Workbooks.Open Filename:=oFile: sSourceName = ActiveWorkbook.Name
Workbooks(sSourceName).Activate
Workbooks(sSourceName).Sheets(1).[A80:Q94].copy
Workbooks(Pivot).Activate
Workbooks(Pivot).Sheets(1).Cells(x + 1, 1).PasteSpecial xlPasteAll
Workbooks(sSourceName).Close False
Next
Application.CutCopyMode = False
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
There are so, so, so many things you can do between Excel & Word. I'm not sure I totally understand your question. The script below may help you; it has definitely served me well over time. If you need something different, please describe your issue more, to better clarify the issue you are facing.
Sub OpenAndReadWordDoc()
Rows("2:1000000").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.ClearContents
Range("A1").Select
' assumes that the previous procedure has been executed
Dim oWordApp As Word.Application
Dim oWordDoc As Word.Document
Dim blnStart As Boolean
Dim r As Long
Dim sFolder As String
Dim strFilePattern As String
Dim strFileName As String
Dim sFileName As String
Dim ws As Worksheet
Dim c As Long
Dim n As Long
'~~> Establish an Word application object
On Error Resume Next
Set oWordApp = GetObject(, "Word.Application")
If Err Then
Set oWordApp = CreateObject("Word.Application")
' We started Word for this macro
blnStart = True
End If
On Error GoTo ErrHandler
Set ws = ActiveSheet
r = 1 ' startrow for the copied text from the Word document
' Last column
n = ws.Range("A1").End(xlToRight).Column
sFolder = "C:\Users\Excel\Desktop\Coding\Microsoft Excel\PWC\Resumes\"
'~~> This is the extension you want to go in for
strFilePattern = "*.doc*"
'~~> Loop through the folder to get the word files
strFileName = Dir(sFolder & strFilePattern)
Do Until strFileName = ""
sFileName = sFolder & strFileName
'~~> Open the word doc
Set oWordDoc = oWordApp.Documents.Open(sFileName)
' Increase row number
r = r + 1
' Enter file name in column A
ws.Cells(r, 1).Value = sFileName
ActiveCell.Offset(1, 0).Select
ActiveSheet.Hyperlinks.Add Anchor:=Sheets("Sheet1").Range("A" & r), Address:=sFileName, _
SubAddress:="A" & r, TextToDisplay:=sFileName
' Loop through the columns
For c = 2 To n
If oWordDoc.Content.Find.Execute(FindText:=Trim(ws.Cells(1, c).Value), _
MatchWholeWord:=True, MatchCase:=False) Then
' If text found, enter Yes in column number c
ws.Cells(r, c).Value = "Yes"
End If
Next c
oWordDoc.Close SaveChanges:=False
'~~> Find next file
strFileName = Dir
Loop
ExitHandler:
On Error Resume Next
' close the Word application
Set oWordDoc = Nothing
If blnStart Then
' We started Word, so we close it
oWordApp.Quit
End If
Set oWordApp = Nothing
Exit Sub
ErrHandler:
MsgBox Err.Description, vbExclamation
Resume ExitHandler
End Sub
Function GetDirectory(path)
GetDirectory = Left(path, InStrRev(path, "\"))
End Function
In this scenario, whatever you put in the headers of B1:K1 (or more to the right) is searched for, each word document in a folder is opened, scanned, and if the string in B1:K1 is found, an 'x' is placed in the same x-y coordinate.
Again, if this doesn't help, please describe your issue better, and I'll post back with alternative solutions. Thanks!!
I have ContentControl drop down box in Word. Once I select an item from a Drop Down list I want to search for that in an Excel document and set the row number equal to a variable.
The code below is what I tried but the Columns("G:G").Find part says its not defined.
Sub findsomething(curRow)
Dim rng As Range
Dim rownumber As Long
curPath = ActiveDocument.path & "\"
Call Set_Variable(curPath)
StrWkShtNm = "Chapters"
If Dir(StrWkBkNm) = "" Then
MsgBox "Cannot find the designated workbook: " & StrWkBkNm, vbExclamation
Exit Sub
End If
Set rng = Columns("G:G").Find(what:=curRow)
rownumber = rng.Row
MsgBox rownumber
' Release Excel object memory
Set xlWkBk = Nothing
Set xlApp = Nothing
Application.ScreenUpdating = True
End Sub
While using more than one MS Office application it is a good idea to specify which application you are targeting:
Excel.Application.ThisWorkbook.Sheets(1).Range("A1").Select
this is what ended up working. you set me on the right track with referencing Excel.
Sub findsomething(curRow)
Dim rng As Long
Dim rownumber As Long
curPath = ActiveDocument.path & "\"
Call Set_Variable(curPath)
StrWkShtNm = "Chapters"
MsgBox "curRow = " & curRow
If Dir(StrWkBkNm) = "" Then
MsgBox "Cannot find the designated workbook: " & StrWkBkNm, vbExclamation
Exit Sub
End If
With xlApp
.Visible = False
Set xlWkBk = .Workbooks.Open(FileName:=StrWkBkNm, ReadOnly:=True, AddToMRU:=False)
With xlWkBk
With .Worksheets(StrWkShtNm)
rng = .Range("G:G").Find(what:=curRow)
MsgBox rng
End With
.Close False
End With
.Quit
End With
' Release Excel object memory
Set xlWkBk = Nothing: Set xlApp = Nothing
Application.ScreenUpdating = True
End Sub
[table - worksheet "output - flat"][1]
I have code below that checks to see if column "NamedRange" in the table attached appears as a named range in the (dstRng) template and if it does exist it returns the value to the right ("report balance"). How can I add a condition where when the user chooses a template it will only return values based on the Ted ID - in the table attached. I have 2 templates and it loops through the two templates however I want the first template to only return values for Ted ID 10004 and template 2 it will only return values for Ted ID 11372 and etc. etc. Hope that makes sense... let me know if u have any questions
Option Explicit
Sub Button4_Click()
Dim Desktop As Variant
Dim Files As Object
Dim Folder As Variant
Dim oShell As Object
Dim Tmplts As Variant ' Templates folder
Dim wsLocal As Worksheet
Dim wsGroup As Worksheet
Dim wb As Object
' Check Box 2 "Select All" must be checked to run the macro.
If ActiveSheet.Shapes("Check Box 2").ControlFormat.Value = xlOff Then Exit Sub
Application.ScreenUpdating = False
Application.EnableEvents = False
' Prompt user to locate the Templates folder.
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show = True Then
Tmplts = .SelectedItems(1)
Else
Exit Sub
End If
End With
Set oShell = CreateObject("Shell.Application")
Set Desktop = oShell.Namespace(0)
' Create the Output folder on the User's Desktop if it does not exist.
Set Folder = Desktop.ParseName("Output")
If Folder Is Nothing Then
Desktop.NewFolder "Output"
Set Folder = Desktop.ParseName("Output")
End If
Set Files = oShell.Namespace(Tmplts).Items
Files.Filter 64, "*.xlsm"
For Each wb In Files
Set wb = Workbooks.Open(Filename:=wb.Path, UpdateLinks:=False)
Call BreakLinks(wb)
On Error Resume Next
Set wsLocal = wb.Worksheets("RVP Local GAAP")
Set wsGroup = wb.Worksheets("RVP Group GAAP")
'unprotect workbook
wsLocal.Unprotect Password:="KqtgH5rn9v"
wsGroup.Unprotect Password:="KqtgH5rn9v"
On Error GoTo 0
' Check that both worksheets exist before updating.
If Not wsLocal Is Nothing And Not wsGroup Is Nothing Then
Call ProcessNamedRanges(wb)
'lock the workbook
wsLocal.Protect Password:="KqtgH5rn9v"
wsGroup.Protect Password:="KqtgH5rn9v"
''MsgBox "Ranges have been updated sucessfully."
' Save the workbook to the folder and close.
On Error Resume Next
wb.SaveAs Filename:=Folder.Path & "\" & wb.Name
ActiveWorkbook.Close True
On Error GoTo 0
End If
Next wb
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Sub ProcessNamedRanges(ByRef wb As Workbook)
Dim dstRng As Range
Dim rng As Range
Dim rngName As Range
Dim rngNames As Range
Dim wks As Worksheet
Set wks = ThisWorkbook.Sheets("Output - Flat")
' Exit if there are no named ranges listed.
If wks.Range("D4") = "" Then Exit Sub
Set rngNames = wks.Range("D4").CurrentRegion
Set rngNames = Intersect(rngNames.Offset(1, 0), rngNames.Columns(2))
'Loop through all the values in NamedRange
For Each rngName In rngNames
' Verify the Named Range exists.
On Error Resume Next
Set dstRng = wb.Names(rngName.Text).RefersToRange
If Err = 0 Then
'Copy the report balance to the Template worksheet in column "G".
dstRng.Value = rngName.Offset(0, 1).Value
Else
'answer = MsgBox("The Named Range """ & rngName.Value & """ Does Not Exist" & vbLf & vbLf & "Continue?", vbYesNo + vbExclamation)
'If answer = vbNo Then Exit Sub
End If
On Error GoTo 0
Next rngName
End Sub
Sub BreakLinks(ByRef wb As Workbook)
Dim i As Long
Dim wbLinks As Variant
wbLinks = wb.LinkSources(xlExcelLinks)
If Not IsEmpty(wbLinks) Then
For i = 1 To UBound(wbLinks)
ActiveWorkbook.BreakLink wbLinks(i), xlLinkTypeExcelLinks
Next i
End If
End Sub