Changing multiple offsets in a VBA loop - excel

I am trying to run a loop where for each account in a range the account number is sent out to a program to search for data. This data is input to another Excel sheet, formatted, and then printed to PDF. This data can only be fetched by one account at a time, so I need it to run through and after saving one pdf to either clear the data and do it again for the next account etc. This process can take a while and so what I am trying to do is create a percentage complete cell.
Is there a way to recognize how many times through the loop it needs to run (say 10) and then update a cell saying we are on loop 1 of 10, 2 of 10, etc.
Here is the code I am running right now:
Public Sub Eligibility()
Dim a As Range, ws As Worksheet
Set ws = ThisWorkbook.Sheets("Starting Page")
'************* This is the loop to check the cells and set the offset value as elgible or ineligible**********
For Each a In ws.Range("G9:G29").Cells
If a.Value = Eligible Then
a.Offset(0, -1).Value = AccountNumber(a.Value)
Data_Import
End If
Next a
'************* Question if we will printscreen**********
Dim AnswerYes As String
Dim AnswerNo As String
AnswerYes = MsgBox("Do you want to print all eligible class action reports?", vbQuestion + vbYesNo, "User Response")
If AnswerYes = vbYes Then Print_PDF
End Sub
G9:G29 is the range and so I wonder if the number could look at that range and tell how many instances of "eligible" there is for the denominator on the count.

Run through the loop adding each of the eligible cells to a VBA collection, then you can get the count of items in the collection (total eligible cells) then use a FOR loop to loop through the items in the collection doing the actual work. percentage complete will be i/count
Something like this (totally untested!)
Public Sub Eligibility()
Dim a As Range, ws As Worksheet
Dim oEligibleCells As VBA.Collection
Dim i As Long
Set ws = ThisWorkbook.Sheets("Starting Page")
'************* This is the loop to check the cells and set the offset value as elgible or ineligible**********
Set oEligibleCells = New VBA.Collection
For Each a In ws.Range("G9:G29").Cells
If a.Value = Eligible Then
Call oEligibleCells.Add(a)
End If
Next a
For i = 1 To oEligibleCells.Count
Set a = oEligibleCells(i)
a.Offset(0, -1).Value = AccountNumber(a.Value)
Data_Import
Application.StatusBar = i / oEligibleCells.Count * 100 & " percent done"
Next i
'************* Question if we will printscreen**********
Dim AnswerYes As String
Dim AnswerNo As String
AnswerYes = MsgBox("Do you want to print all eligible class action reports?", vbQuestion + vbYesNo, "User Response")
If AnswerYes = vbYes Then Print_PDF
End Sub

Related

How to select a specific type of tracked change in a word table and copy it to excel?

I have a unique situation I am trying to find a way to implement:
I am working with word documents that are simple tables.. all of the information in the word doc is in a table. Some are hundreds of pages long, and are revised regularly. What I am trying to do is to (in excel from a macro) open the word document, scan it and copy over to excel only those rows from the table that are insertions.
I have managed to cobble together from various sources the code that will open the word doc and copy over ANY track changes... But for the life of me I cannot see or find a way to limit it to insertions, I'm hoping that someone may have some ideas...
Here is the code I am using now that works to bring over all tracked changes in the proper columns:
'declare variables
Dim ws As Worksheet
Dim WordFilename As Variant
Dim Filter As String
Dim WordDoc As Object
Dim tbNo As Long
Dim RowOutputNo As Long
Dim RowNo As Long
Dim ColNo As Integer
Dim tbBegin As Integer
Set ws = Worksheets("Analysis")
Filter = "Word File New (*.docx), *.docx," & _
"Word File Old (*.doc), *.doc,"
'clear all of the content in the worksheet where the tables from the Word document are to be imported
ws.Cells.ClearContents
'if you only want to clear a specific range, replace .Cells with the range that you want to clear
'displays a Browser that allows you to select the Word document that contains the table(s) to be imported into Excel
WordFilename = Application.GetOpenFilename(Filter, , "Select Word file")
If WordFilename = False Then Exit Sub
'open the selected Word document
Set WordDoc = GetObject(WordFilename)
With WordDoc
tbNo = WordDoc.Tables.Count
If tbNo = 0 Then
MsgBox "This document contains no tables"
End If
'nominate which row to begin inserting the data from. In this example we are inserting the data from row 1
RowOutputNo = 1
'go through each of the tables in the Word document and insert the data from each of the cells into Excel
For tbBegin = 1 To tbNo
With .Tables(tbBegin)
For RowNo = 1 To .rows.Count
For ColNo = 1 To .Columns.Count
'-----This code works to only select revisions ----------------
'-----Next step - make it only select insertions -
' OR - let it mark what kind of revision it is-----
Set rng = .Cell(RowNo, ColNo).Range
'don't include the "end of cell" marker in the checked range
'rng.MoveEnd wdCharacter, -1
numRevs = rng.Revisions.Count
If numRevs > 0 Then
ws.Cells(RowOutputNo, ColNo) = Application.WorksheetFunction.Clean(.Cell(RowNo, ColNo).Range.Text)
End If
Next ColNo
RowOutputNo = RowOutputNo + 1
Next RowNo
End With
RowOutputNo = RowOutputNo
Next tbBegin
End With
End Sub
For example:
If numRevs > 0 Then
For revIdx = 1 To numRevs
If Rng.Revisions(revIdx).Type = 1 Then
'it's an insert
End If
Next revIdx

How to call a subroutine that has parameters?

I am working on an Excel Userform to generate a report for a lot entered on a given day.
The report is stored in a Word document which contains the results of between 1 and 8 quality samples (number of samples varies by lot).
The Userform is meant to load in Excel, receive a lot number and date from the user, retrieve samples from that day and lot from a different sheet in the Excel workbook and then copy the data into a new Word doc based on a custom template.
The input part of the Userform and the Word template are both set up. I hit a snag on the event handling procedure for the "OK" button.
The form's OK button event handler gives
compile error
on
Sub makeReport(lNum As Integer, pDay As Date)
The editor isn't indicating an issue in my makeReport method; the call to makeReport in the event handler is highlighted red.
I am using the Excel 2013 VBA editor, and neither the built-in debugging tools in Excel, the Microsoft online VBA docs nor various forum posts found via Google can give me a complete answer to what is wrong and how to fix it.
OK Button event handler
Private Sub OKButton_Click() 'OK button
'Declare variables
Dim lNum As Integer
Dim pDay As Date
Dim name As String
Dim nStr As String
Dim dStr As String
'Error handler for incorrect input of lot number or pack date
On Error GoTo ErrorHandler
'Convert input values to correct types
nStr = TextBox1.Value
dStr = TextBox2.Value
'Set variable values
lNum = CInt(nStr)
MsgBox ("Step 1 Done" + vbCrLf + "Lot Number: " + nStr)
pDay = Format(dStr, "mm/dd/yyyy")
MsgBox ("Step 2 Done" + vbCrLf + "Pack Date: " + dStr)
name = nameDoc(pDay, lNum)
MsgBox ("Step 3 Done" + vbCrLf + "Report Name: " + name)
'Check for existing report
If Dir("\\CORE\Miscellaneous\Quality\Sample Reports\" + name) Then
MsgBox ("The file " + name + "already exists. Check \\CORE\Miscellaneous\Quality\Sample Reports for the report.")
Unload UserForm1
Exit Sub
Else
makeReport(lNum, pDay)
End If
'Unload User Form and clean up
Unload UserForm1
Exit Sub
ErrorHandler:
MsgBox ("Error. Please Try Again.")
'Unload UserForm1
End Sub
makeReport sub
Sub makeReport(lNum As Integer, pDay As Date)
'Template Path: \\CORE\Miscellaneous\Quality\Sample Reports\Template\Defect Report.dotm
'Save path for finished report: \\CORE\Miscellaneous\Quality\Sample Reports
'Generate doc name
Dim name As String
name = nameDoc(pDay, lNum)
'Initialize word objects and open word
Dim wApp As Word.Application
Dim wDoc As Word.Document
Set wApp = CreateObject("Word.Application")
wApp.Visible = True
Set wDoc = wApp.Documents.Add(Template:=("\\CORE\Miscellaneous\Quality\Sample Reports\Template\Defect Report.dotm"), NewTemplate:=False, DocumentType:=0)
'Initialize excel objects
Dim wbBook As Workbook
Dim wsSheet As Worksheet
Set wbBook = ThisWorkbook
Set wsSheet = wbBook.Worksheets("Defect Table")
'Fill in lot number and date at top of report
With wDoc
.Application.Selection.Find.Text = "<<date>>"
.Application.Selection.Find.Execute
.Application.Selection = pDay
.Application.Selection.EndOf
.Application.Selection.Find.Text = "<<lot>>"
.Application.Selection.Find.Execute
.Application.Selection = lNum
End With
'Initialize loop variables
Dim row1 As Integer
Dim row2 As Integer
Dim diff As Integer
Dim more As Boolean
Dim num As Integer, num1 As Integer, col As Integer
Dim count As Integer
count = 0
diff = 0
more = False
'Do while loop allows variable number of samples per day
Do While count < 8
'Checks for correct starting row of day
row1 = WorksheetFunction.Match(lNum, wsSheet.Range(), 0)
row2 = WorksheetFunction.Match(pDay, wsSheet.Range(), 0)
If IsError(row1) Or IsError(row2) Then
'Breaks for loop once all samples have been copied over
Exit Do
ElseIf row1 = row2 Then
num = 4
num1 = num
Do While num < 31
'Column variable
col = count + 1
'Copies data to word doc, accounting for blank rows in the word table
Select Case num
Case 6, 10, 16, 22, 30
num1 = num1 + 1
Case Else
num1 = num1
End Select
ActiveDocument.Tables(1).Cell(num1, col) = ActiveSheet.Range().Cells(row1, num)
num = num + 1
Next
Else
'Deiterates count to adjust for differences between row1 and row2
count = count - 1
End If
'Moves the collision to below row1 to allow MATCH to find next viable result
diff = row1 + 1
wsSheet = wsSheet.Range().Offset(diff, 0)
'Iterates count
count = count + 1
Loop
'Zeroes out word objects
Set wdDoc = Nothing
Set wdApp = Nothing
'Saves Document using regular name format for ease of access
wDoc.SaveAs2 Filename:="\\CORE\Miscellaneous\Quality\Sample Reports\" + name, FileFormat:=wdFormatDocumentDefault, AddtoRecentFiles:=False
End Sub
makeReport(lNum, pDay)
The brackets here imply that you are expecting something to be returned which can't happen as makeReport is a Sub not a Function. This is causing the compile error. To correct just remove the brackets.
You also have an additional problem as there is a mismatch with pDay. When you format a date you convert it from a Date, which is just a numeric value, into a String.
In OKButton_Click() try changing:
pDay = Format(dStr, "mm/dd/yyyy")
to:
pDay = CDate(dStr)
so that it matches the data type expected by makeReport. You can then apply the required formatting in makeReport by changing
.Application.Selection = pDay
to
.Application.Selection = Format(pDay, "mm/dd/yyyy")

How to call MailItem.Display method when clicking on a table cell?

I need to call the Outlook MailItem.Display method when clicking on a specific cell in a table column in Excel.
Below is my module for filling out table.
' This module performs email retrieval and viewing. Dynamically adds email information to a table and creates
' links that open Outlook mailitems in a modal window.
Option Explicit
'Initialize Outlook objects
Dim appOL, appNS, appFolder, email As Object
'initialize ListObject
Dim tbl As ListObject
'Add email information to tbl_email_data
Public Sub addDataToEmailTable()
'GetDefaultFolder(6) is "Inbox" of whoever is signed into Outlook desktop version.
'Does not account for subfolders in Inbox and does not work with Web Outlook version.
Set appOL = CreateObject("Outlook.Application")
Set appNS = appOL.GetNamespace("MAPI")
Set appFolder = appNS.GetDefaultFolder(6)
'initialize table
Set tbl = ThisWorkbook.Worksheets("Email").ListObjects("tbl_email_data")
Dim rowCount As Long
rowCount = 1
If tbl.DataBodyRange Is Nothing Then
tbl.ListRows.Add
End If
'loop through emails and put information into tbl_email_data
For Each email In appFolder.Items
If email.Unread = True Then
tbl.DataBodyRange.Cells(rowCount, 1).Value2 = "Unread"
Else
tbl.DataBodyRange.Cells(rowCount, 1).Value2 = "Read"
End If
tbl.DataBodyRange.Cells(rowCount, 2).Value2 = email.SenderName
tbl.DataBodyRange.Cells(rowCount, 3).Value2 = email.SentOn
tbl.DataBodyRange.Cells(rowCount, 4).Value2 = email.Subject
rowCount = rowCount + 1
Next email
End Sub
I was going to create a userform with a comboBox so when selected a textbox fills with item.body.
This does not account for embedded images, and HTML formatted messages.
I saw Outlook has a method for mailitem that opens the email directly without exiting Excel.
So I figured out how to call the MailItem.Display method based on a table that represents email information in the Inbox folder of Outlook. Lots of trial and error but I got it to work. Below is the full code for the module that will handle all of this.
Option Explicit
Public excelInbox As Collection
Dim appOL, appNS, appInbox, appItem As Object
Public isOnline As Boolean
Public Function checkConnection(status As Boolean)
Set appOL = CreateObject("Outlook.Application")
Set appNS = appOL.GetNameSpace("MAPI")
If appNS.Offline = True Then
MsgBox "Outlook account is not connected to Exchange server. Please verify network connection to get updated Inbox preview"
status = False
Set appNS = Nothing
Set appOL = Nothing
Else
MsgBox "Outlook account is online"
status = True
End If
Set appInbox = appNS.GetDefaultFolder(6)
Set excelInbox = New Collection
End Function
Public Sub makeExcelInbox()
Call checkConnection(isOnline)
If isOnline <> True Then Exit Sub
Set appInbox = appNS.GetDefaultFolder(6) '6 is the enumeration for Inbox root folder in Outlook.
'loop and place only emails into excel Inbox.
For Each appItem In appInbox.Items
If appItem.Class = 43 Then excelInbox.Add appItem '43 represents a mail item in Outlook.
Next appItem
End Sub
Public Sub makeEmailPreviewTable()
Call makeExcelInbox
If excelInbox.Count <> 0 Then
Dim tbl As ListObject
Dim rowCount As Integer
Set tbl = ws_email.ListObjects("tbl_emailData")
rowCount = 1
For Each appItem In excelInbox
If appItem.Unread = True Then
tbl.DataBodyRange.Cells(rowCount, 1).Value2 = "Unread"
Else
tbl.DataBodyRange.Cells(rowCount, 1).Value2 = "Read"
End If
tbl.DataBodyRange.Cells(rowCount, 2).Value2 = appItem.SenderName
tbl.DataBodyRange.Cells(rowCount, 3).Value2 = appItem.SentOn
tbl.DataBodyRange.Cells(rowCount, 4).Value2 = appItem.Subject
rowCount = rowCount + 1
Next appItem
Set tbl = Nothing
ElseIf excelInbox.Count = 0 Then MsgBox "No messages to show in Inbox Preview."
End If
End Sub
Public Function getEmailForDisplay(Target As Range)
'Call makeExcelInbox
For Each appItem In excelInbox
If Target.Value = appItem.Subject Then appItem.Display
Next appItem
End Function
I used the selection change event in the worksheet that has the table to pass the target range value to a function that checks if that value is the same as the subject property of an email in the inbox. It is not the prettiest code, but for any others that come across this with a similar problem this should at least get you on the right path. Here is the worksheet code for event below.
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'Check for selection of a cell in tbl_emailData column Subject, then pass the value to a function.
Dim rng As Range
Dim tableRange As Range
Set tableRange = ListObjects("tbl_emailData").DataBodyRange
Dim rowCount As Long
rowCount = 1
If Intersect(Target, tableRange) Is Nothing Then Exit Sub
'check for valid target location
For Each rng In tableRange
On Error GoTo ErrorHandler
If Target = tableRange(rowCount, 4) Then
Call getEmailForDisplay(Target)
Else
rowCount = rowCount + 1
End If
Next rng
ErrorHandler:
Exit Sub
End Sub
Just an important note, I am still designing this program so if you sample the code you have to make sure you have a table called "tbl_emailData" and a worksheet called "ws_email". Then when you want to run the code, make sure to run the sub "makeEmailPreviewTable" first. In my design the worksheets and cells will all be locked so only the subject column cells will be selectable, this prevents run-time errors in case the user selects more than one cell.
Update: Added errorhandling to the selection event to ignore multi-selection errors. This will ignore, and then when a proper cell is selected then display the email in a Outlook modal.

Get Value and Position of Checkbox in Word Table to Copy Entire Table to Excel

I have a Word file with approximately 10 pages and 20 tables. Some of these tables have checkboxes. I want to copy these tables into an Excel file.
The following code copies all tables from my Word file into my Excel file:
Sub Import()
Option Explicit
Dim wb As Workbook
Dim sh As Worksheet
Dim sheet As Worksheet
Dim lzeile As Integer
Set wb = ActiveWorkbook
Set sh = wb.ActiveSheet
Set sheet = wb.Worksheets("Tabelle1")
Dim Btxt As Object
Set Btxt = CreateObject("Word.Application")
Btxt.Visible = True
Btxt.documents.Open "C:\Users\*.doc" '*=path
lzeile = 0
For i = 1 To 20
Btxt.ActiveDocument.Tables(i).Range.Copy
Application.Goto sheet.Cells(1 + lzeile, 1)
sheet.PasteSpecial Format:="HTML", Link:=False, DisplayAsIcon:=False
lzeile = sheet.Cells(Rows.Count, 1).End(xlUp).Row
lzeile = lzeile + 1
sheet.Cells(lzeile, 1) = "Tabelle" & i
Next i
Btxt.Quit
Set Btxt = Nothing
Set wb = Nothing
Set sh = Nothing
End Sub
It does not copy checkboxes or the value (0 = not checked / 1 = checked) of the checkbox.
I can write the value of a checkbox into a cell in my excel sheet with this line:
sheet.Cells(j, 10) = Btxt.ActiveDocument.Tables(i).FormFields.Item("Kontrollkästchen" & j).Result
With a loop j over all "Kontrollkästchen" (german translation of contentcontrol or formfield item) so basically the name of all formfield items in this Word file.
How can I get the position of these formfield items or identify which formfield item / ContentControl is in which table?
I tried to go through all rows and columns in each table because none of them are larger than 10x10. But I can´t find a way to check if a checkbox is maybe in table 3 on column 5 row 5 and then read the name of this checkbox to a safe the value (0 / 1) in the Excel cell on the same position in my copied table.
The solution depends on whether they're formfields or content controls.
Assuming they're formfields:
Sub Demo()
Dim i As Long, j As Long, Rng As Range
With ActiveDocument
For i = .FormFields.Count To 1 Step -1
With .FormFields(i)
If .Type = wdFieldFormCheckBox Then
j = Abs(.CheckBox.Value)
Set Rng = .Range
.Delete
Rng.Text = j
End If
End With
Next
End With
End Sub
Assuming they're content controls:
Sub Demo()
Dim i As Long, j As Long, Rng As Range
With ActiveDocument
For i = .ContentControls.Count To 1 Step -1
With .ContentControls(i)
If .Type = wdContentControlCheckBox Then
j = Abs(.Checked)
Set Rng = .Range
.Delete
Rng.Text = j
End If
End With
Next
End With
End Sub
For the sake of simplicity and clarity, the sample code below leaves out the parts having to do with Excel, as well as creating the instance of the Word Application. It shows only how to access the Word document's checkboxes and convert those to static values.
At the end, also, the document is closed without saving changes, which means forms protection and the checkboxes should be left intact - the macro will not have affected them.
Note: You should have Option Explicit at the top of the code page, not inside a "Sub".
How it works
The document to be processed is opened and at that moment set to an object (doc). Use this instead of ActiveDocument as it will be much clearer and, in case the user would try to do something, won't affect macro execution.
If the document has forms protection, this must be turned off in order to delete the checkboxes and insert static values.
Then all the form fields are looped. If they are checkboxes, the value is determined, the checkbox removed and the value assigned to the range the checkbox occupied.
After this has completed comes the code to transfer data to Excel. Then the document is closed without saving changes.
Sub ConvertCheckBoxesToValues()
Dim ff As Object ' Word.FormField
Dim doc As Object ' Word.Document
Dim cbValue As String
Dim rngFF As Object ' Word.Range
Set doc = Btxt.Documents.Open("C:\Users\*.doc") '*=path
If doc.ProtectionType <> -1 Then 'wdNoProtection
doc.Unprotect
End If
For Each ff In doc.FormFields
If ff.Type = 71 Then 'wdFieldFormCheckBox
If ff.CheckBox.value = True Then
cbValue = "1"
Else
cbValue = "0"
End If
Set rngFF = ff.Range
ff.Delete
rngFF = cbValue
End If
Next
'Transfer the information to Excel, then
doc.Close 0 'wdDoNotSaveChanges
End Sub

Excel listing named range in a worksheet and get the value

How to obtain a list of named range exist in a specific worksheet that start with particular string (for example all named range that start with total) and grab the value? I am trying to do Sub Total and Grand Total of accommodation cost based on the date. I will assign an unique name for each Sub Total based on the Date group. Then, I have a button that need to be clicked when it finishes to calculate the Grand Total based on the Named Range that I've assigned uniquely to each Sub Total.
Below is the code I wrote to do the Grand Total:
Sub btnTotal()
Dim Total, LastRowNo As Long
LastRowNo = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count
Total = 0
For Each N In ActiveWorkbook.Names
Total = Total + IntFlight.Range(N.Name).Value
Next N
IntFlight.Range("$P" & LastRowNo).Select
Selection.NumberFormat = "$* #,##0.00;$* (#,##0.00);$* ""-""??;#"
With Selection
.Font.Bold = True
End With
ActiveCell.FormulaR1C1 = Total
End Sub
Note: the IntFlight from "Total = Total + IntFlight.Range(N.Name).Value" is the name of my worksheet.
The only problem with above code, it will looking all named range exist in the workbook. I just need to find named range exist in one particular worksheet, which start with given string and the row number (total26: means Sub Total from row 26) and then grab the value to be sum-ed as Grand Total.
Any ideas how to do this? Been spending 2 days to find the answer.
Thanks heaps in advance.
EDIT 1 (Solution Provided by Charles Williams with help from belisarius):
This is what I have done with the code from Charles Williams:
Option Explicit
Option Compare Text
Sub btnIntFlightsGrandTotal()
Dim Total, LastRowNo As Long
LastRowNo = FindLastRowNo("International Flights")
Dim oNM As Name
Dim oSht As Worksheet
Dim strStartString As String
strStartString = "IntFlightsTotal"
Set oSht = Worksheets("International Flights")
For Each oNM In ActiveWorkbook.Names
If oNM.Name Like strStartString & "*" Then
If IsNameRefertoSheet(oSht, oNM) Then
Total = Total + Worksheets("International Flights").Range(oNM.Name).Value
End If
End If
Next oNM
IntFlights.Range("$P" & LastRowNo).Select
Selection.NumberFormat = "$* #,##0.00;$* (#,##0.00);$* ""-""??;#"
With Selection
.Font.Bold = True
End With
ActiveCell.FormulaR1C1 = Total
End Sub
Function FindLastRowNo(SheetName As String) As Long
Dim oSheet As Worksheet
Set oSheet = Worksheets(SheetName)
FindLastRowNo = oSheet.UsedRange.Row + oSheet.UsedRange.Rows.Count
End Function
Thank you all for your help. Now, I need to come up with my own version for this script.
Here is some code that checks if a Defined Name starts with a string and refers to a range within the used range of a given worksheet and workbook.
Option Explicit
Option Compare Text
Sub FindNames()
Dim oNM As Name
Dim oSht As Worksheet
Dim strStartString As String
strStartString = "Total"
Set oSht = Worksheets("TestSheet")
For Each oNM In ActiveWorkbook.Names
If oNM.Name Like strStartString & "*" Then
If IsNameRefertoSheet(oSht, oNM) Then
MsgBox oNM.Name
End If
End If
Next oNM
End Sub
Function IsNameRefertoSheet(oSht As Worksheet, oNM As Name) As Boolean
Dim oSheetRange As Range
IsNameRefertoSheet = False
On Error GoTo GoExit
If Not oSht Is Nothing Then
If Range(oNM.Name).Parent.Name = oSht.Name And _
Range(oNM.Name).Parent.Parent.Name = oSht.Parent.Name Then
Set oSheetRange = oSht.Range("A1").Resize(oSht.UsedRange.Row + oSht.UsedRange.Rows.Count - 1, oSht.UsedRange.Column + oSht.UsedRange.Columns.Count - 1)
If Not Intersect(Range(oNM.Name), oSheetRange) Is Nothing Then IsNameRefertoSheet = True
Set oSheetRange = Nothing
End If
End If
Exit Function
GoExit:
End Function
The following function will output all the names and their totals in your Workbook.
I think it is the basic block you need to get your code running.
Sub btnTotal()
For Each N In ActiveWorkbook.Names
MsgBox N.Name + " " + CStr(Application.WorksheetFunction.Sum(Range(N)))
Next N
End Sub
Edit
Answering your comment:
Define your names in this way:
Then (and only then) the following code works:
Sub btnTotal()
For Each N In ActiveSheet.Names
If (InStr(N.Name, "!Total") <> 0) Then
MsgBox N.Name + " " + CStr(Application.WorksheetFunction.Sum(Range(N)))
End If
Next N
End Sub
If you do not define the scope of the names correctly you need a lot of extra work in your code.
Edit
As you forgot to mention that you are still working with Excel 2003, here you will find an addin to manage name scoping in that version. See screen cap below
HTH

Resources