2

I have the following formula ( please note the file path, booklet name and sheet name are shown as generic here)

=IF('C:Potato\documents\[book.xlsm]sheet1'!$J$5>0,'C:\documents\[book.xlsm]sheet1'!$J$5,'C:\documents\[book.xlsm]sheet1'!$B$6)-'C:\documents\[book.xlsm]sheet1'!$J$5

The above formula works without issue.

Now my question: I have the file path in a cell, lets say K21 in the spread sheet as such:

C:Potato\documents\

I am not allowed to alter the address format of this cell. The path points to the folder containing the booklet2. Note my formula is in booklet1.

What I want to do is to be able able to change this address at K21, dynamically, without having to change the formula. as well as duplicate the formula in the subsequent rows and have the K21 change dynamically to K22, K23 ,, etc. You get the picture.

So what I am looking for is in theory like this:

=IF('**K21**\[book.xlsm]sheet1'!$J$5>0,'C:\documents\[book.xlsm]sheet1'!$J$5,'**k21**\[book.xlsm]sheet1'!$B$6)-'**k21**\[book.xlsm]sheet1'!$J$5

and when I copy it into the row below to change like this

=IF('**K22**\[book.xlsm]sheet1'!$J$5>0,'C:\documents\[book.xlsm]sheet1'!$J$5,'**k22**\[book.xlsm]sheet1'!$B$6)-'**k22**\[book.xlsm]sheet1'!$J$5

now i know the above doesn't work, because the cell K21 does not get interpreted as a dynamic cell pointer.

I have been researching the INDIRECT function, have had no luck with it. Also I don't think it would be of use to me, as I don't want to have the other booklet open.

Any help would be appreciated.

see my research links:

David
  • 5,882
  • 3
  • 33
  • 44
Mel
  • 174
  • 1
  • 11

1 Answers1

0

I made some researches about your request and it's seem that there is no way to do this. Depending of your Excel version (year,x32 x64), I found those following solutions (I have Excel 2013 x64 and none works for me) :

  1. MoreFunc : MOREFUNC is an add-in for Excel offering 67 new worksheet functions for Excel 95-2007 and probably 2010 & 2013 for 32 bits edition. It contain this function : INDIRECT.EXT: returns the contents of a cell or a range contained in a closed workbook

MoreFunc download

  1. VBA function : I found 2 vba functions. As the first solution, it's work depending Excel version.

    - IndirectEx() : Extended INDIRECT Function v1.0 by Wilson So.

'------------------------------------ 'Extended INDIRECT Function v1.0 '------------------------------------ 'Copyright (c) 2009 Wilson So. 'E-mail: @ '------------------------------------ 'Credits: '- Designed and written by Wilson So. '- The 'CreateObject("Excel.Application")' trick was inspired by Harlan Grove's PULL function source code. '------------------------------------ 'This is an open source. You can freely redistribute and modify it, but please kindly give credit to the contributers. 'Please also kindly report any bugs/suggestions through e-mail or in the forums where I posted it. '------------------------------------ 'How to use: '- Basically same as INDIRECT() in Excel - the same concept for the ref_text parameter. '- To update the static memory for a particular reference, ' type TRUE in the second parameter (just one of the IndirectEx() containing that reference) ' and calculate it once. '------------------------------------ 'Features: '- You can refer to the closed workbook data. '- The retrieved closed workbook data will be stored in the static memory, ' so in the next time, the closed workbook will not be opened again for fast retrieve. '- A range instead of an array will be returned if the path is omitted in the ref_text, ' so it still works fine if the user refers to an enormous array, e.g. "Sheet1!1:65536". '- You can use it inside INDEX(), VLOOKUP(), MATCH() etc. '- You can use it with OFFSET(), but only for opened workbook data. '- The procedure will not blindly retrieve all the data as requested; ' it will not retrieve data beyond the "Ctrl + End" cell, in order to keep the memory as small as possible. '- #NUM! will be returned in case of lack of memory. '- #REF! will be returned in case of a wrong path. '- #VALUE! will be returned in case of other errors. '------------------------------------ 'Known issues: '- Due to the use of SpecialCells(), #VALUE! will be returned if the worksheet for a closed workbook is protected. '-----------------------------------

-

Function IndirectEx(ref_text As String, Optional refresh_memory As Boolean = False) As Variant
    On Error GoTo ClearObject

    Dim RefName As String
    Dim SheetName As String
    Dim WBName As String
    Dim FolderName As String

    Dim vExcel As Object
    Dim vWB As Workbook

    Static dbOutput() As Variant
    Static dbKey() As String
    Static dbTotalOutput As Integer
    Dim dbIndex As Integer

    Dim UserEndRow As Long, UserEndCol As Integer
    Dim RealEndRow As Long, RealEndCol As Integer
    Dim EndRow As Long, EndCol As Integer
    Dim RangeHeight As Long, RangeWidth As Integer

    GetNames ref_text, RefName, SheetName, WBName, FolderName

    If dbTotalOutput = 0 Then
        ReDim dbOutput(1 To 1) As Variant
        ReDim dbKey(1 To 1) As String
    End If

    For i = 1 To dbTotalOutput
        If dbKey(i) = FolderName & WBName & "!" & SheetName & "!" & RefName Then
            dbIndex = i
        End If
    Next

    If dbIndex = 0 Or refresh_memory Then
        If dbIndex = 0 Then
            dbTotalOutput = dbTotalOutput + 1
            dbIndex = dbTotalOutput
            ReDim Preserve dbOutput(1 To dbTotalOutput) As Variant
            ReDim Preserve dbKey(1 To dbTotalOutput) As String
            dbKey(dbIndex) = FolderName & WBName & "!" & SheetName & "!" & RefName
        End If
        If FolderName = "" Then
            Set dbOutput(dbIndex) = Workbooks(WBName).Worksheets(SheetName).Range(RefName)
        ElseIf Dir(FolderName & WBName) <> "" Then
            Set vExcel = CreateObject("Excel.Application")
            Set vWB = vExcel.Workbooks.Open(FolderName & WBName)
            With vWB.Sheets(SheetName)
                On Error GoTo ClearObject
                UserEndRow = .Range(RefName).Row + .Range(RefName).Rows.Count - 1
                UserEndCol = .Range(RefName).Column + .Range(RefName).Columns.Count - 1
                RealEndRow = .Range("A1").SpecialCells(xlCellTypeLastCell).Row
                RealEndCol = .Range("A1").SpecialCells(xlCellTypeLastCell).Column
                EndRow = IIf(UserEndRow < RealEndRow, UserEndRow, RealEndRow)
                EndCol = IIf(UserEndCol < RealEndCol, UserEndCol, RealEndCol)
                RangeHeight = EndRow - .Range(RefName).Row + 1
                RangeWidth = EndCol - .Range(RefName).Column + 1
                On Error Resume Next
                dbOutput(dbIndex) = .Range(RefName).Resize(RangeHeight, RangeWidth).Value
                If Err.Number <> 0 Then
                    IndirectEx = CVErr(xlErrNum)
                    GoTo ClearObject
                End If
            End With
            On Error GoTo ClearObject
            vWB.Close False
            vExcel.Quit
            Set vExcel = Nothing
        Else
            IndirectEx = CVErr(xlErrRef)
            Exit Function
        End If
    End If

    If TypeOf dbOutput(dbIndex) Is Range Then
        Set IndirectEx = dbOutput(dbIndex)
    Else
        IndirectEx = dbOutput(dbIndex)
    End If

    Exit Function

ClearObject:
    On Error Resume Next
    If Not (vExcel Is Nothing) Then
        vWB.Close False
        vExcel.Quit
        Set vExcel = Nothing
    End If
End Function
Private Sub GetNames(ByVal ref_text As String, ByRef RefName As String, ByRef SheetName As String, ByRef WBName As String, ByRef FolderName As String)
    Dim P_e As Integer
    Dim P_b1 As Integer
    Dim P_b2 As Integer
    Dim P_s As Integer

    P_e = InStr(1, ref_text, "!")
    P_b1 = InStr(1, ref_text, "[")
    P_b2 = InStr(1, ref_text, "]")
    P_s = InStr(1, ref_text, ":\")

    If P_e = 0 Then
        RefName = ref_text
    Else
        RefName = Right$(ref_text, Len(ref_text) - P_e)
    End If
    RefName = Replace$(RefName, "$", "")

    If P_e = 0 Then
        SheetName = Application.Caller.Parent.Name
    ElseIf P_b1 = 0 Then
        SheetName = Left$(ref_text, P_e - 1)
    Else
        SheetName = Mid$(ref_text, P_b2 + 1, P_e - P_b2 - 1)
    End If
    SheetName = Replace$(SheetName, "'", "")

    If P_b1 = 0 Then
        WBName = Application.Caller.Parent.Parent.Name
    Else
        WBName = Mid$(ref_text, P_b1 + 1, P_b2 - P_b1 - 1)
    End If

    If P_s = 0 Then
        FolderName = ""
    Else
        FolderName = Left$(ref_text, P_b1 - 1)
    End If
    If Left$(FolderName, 1) = "'" Then FolderName = Right$(FolderName, Len(FolderName) - 1)
End Sub

- PULL() : by Harlan Grove

'inspired by Bob Phillips and Laurent Longre 'but written by Harlan Grove '----------------------------------------------------------------- 'Copyright (c) 2003 Harlan Grove. ' 'This code is free software; you can redistribute it and/or modify 'it under the terms of the GNU General Public License as published 'by the Free Software Foundation; either version 2 of the License, 'or (at your option) any later version. '-----------------------------------------------------------------

Function pull(xref As String) As Variant
    Dim xlapp As Object, xlwb As Workbook
    Dim b As String, r As Range, c As Range, n As Long

    pull = Evaluate(xref)

    If CStr(pull) = CStr(CVErr(xlErrRef)) Then
        On Error GoTo CleanUp                    'immediate clean-up at this point

        Set xlapp = CreateObject("Excel.Application")
        Set xlwb = xlapp.Workbooks.Add           'needed by .ExecuteExcel4Macro

        On Error Resume Next                     'now clean-up can wait

        n = InStr(InStr(1, xref, "]") + 1, xref, "!")
        b = Mid(xref, 1, n)

        Set r = xlwb.Sheets(1).Range(Mid(xref, n + 1))

        If r Is Nothing Then
            pull = xlapp.ExecuteExcel4Macro(xref)
        Else
            For Each c In r
                c.Value = xlapp.ExecuteExcel4Macro(b & c.Address(1, 1, xlR1C1))
            Next c

            pull = r.Value
        End If

CleanUp:
        If Not xlwb Is Nothing Then xlwb.Close 0
        If Not xlapp Is Nothing Then xlapp.Quit
        Set xlapp = Nothing
    End If
End Function
QHarr
  • 83,427
  • 12
  • 54
  • 101
JC Guidicelli
  • 1,296
  • 7
  • 16