Excel vba函数使用已关闭工作簿中的变量获取值

时间:2016-10-25 11:24:04

标签: excel-vba vba excel

我有以下函数用于从已关闭的工作簿中获取数据:

Public Function GetValue(path, file, sheet, ref)
'   Retrieves a value from a closed workbook
    Dim arg As String
'   Make sure the file exists
    If Right(path, 1) <> "\" Then path = path & "\"
    If Dir(path & file) = "" Then
        GetValue = "File Not Found"
        Exit Function
    End If
'   Create the argument
    arg = "'" & path & "[" & file & "]" & sheet & "'!" & _
      Range(ref).Range("A1").Address(, , xlR1C1)
'   Execute an XLM macro
    GetValue = ExecuteExcel4Macro(arg)
End Function

然后我有以下测试程序:

Sub TestGetValue()
    p = Range("B2").Value
    f = Range("B3").Value
    s = "TOTAL"
    a = "D" & ActiveCell.Row + 3
    MsgBox GetValue(p, f, s, a)
End Sub

但是,如果我在excel单元格中使用GetValue函数提供与例程中完全相同的所有4个参数,它总是会抛出#VALUE!错误。

所以问题是,为什么它在例程中工作而不是在被称为函数时?任何指针将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:0)

经过多次尝试,我找到了3个解决方案:

  1. 使用&#34; ExecuteExcel4Macro&#34;
  2. 的功能
  3. 通过vba过程在后台打开其他工作簿,然后复制/粘贴数据
  4. 通过vba过程创建外部引用,然后只保留值
  5. 第一个能够将其用作excel自定义公式时,它是最慢的,尤其是当您需要来自特定范围的数据时。因此,我不建议使用此选项,因为它会大大降低您的工作簿速度。

    第二个选项虽然速度更快,但仍需要大约15秒才能从两个工作簿中的多个范围获取数据。

    第三种选择是最快的。就像瞬间不到1秒的执行时间,在此期间从2个已关闭的工作簿和不同的范围中提取数据。

    这是第3个选项的程序:

    import java.util.*;
    import java.io.*;
    
    public class Array {
    
        public static void main(String[] args) {
    
            Scanner scan = new Scanner(System.in);
            String newLine = System.lineSeparator();
            String choiceInput;
            boolean stop = false;
            boolean firstTime = true;
    
    
            while (stop == false){
    
                if (firstTime == true) {
                    System.out.println("Welcome To The Multiplications Table Creator!" + newLine + newLine + "Would you like to:" + newLine + newLine + "Create          Print          Exit" + newLine + newLine + "Please enter one of the above in the space below: ");
                }
                else {
                    System.out.println("Welcome Back!" + newLine + newLine + "Would you like to:" + newLine + newLine + "Create          Print          Exit" + newLine + newLine + "Please enter one of the above in the space below: ");
                }
                choiceInput = scan.nextLine().toUpperCase();
    
                if (choiceInput.equals("CREATE")) {
                    createArray();
                    firstTime = false;
    
                    for (int count = 0; count < 10; count++) {
                        System.out.println(newLine);
                    }
    
                }
                else if (choiceInput.equals("PRINT")) {
                    print();
                    firstTime = false;
                }
                else if (choiceInput.equals("EXIT")) {
                    for (int count = 0; count < 10; count++) {
                        System.out.println(newLine);
                    }
                    System.out.print("Thank you for using the program!");
                    for (int count = 0; count < 2; count++) {
                        System.out.println(newLine);
                    }
                    stop = true;
                }
                else System.out.println("You did not enter one of the above!");
            }
        }
    
        public static int[][] createArray() {
    
            Scanner s = new Scanner(System.in);
            String newLine = System.lineSeparator();
            int a;
            int b;
    
            System.out.print("How big would you like your multiplication table to be? (A x B)" + newLine + "A: ");
            a = s.nextInt();
            System.out.println(a + " x ");
            b = s.nextInt();
    
            int[][] multArray = new int[a][b];
    
            for (int countA = 1; countA <= a; countA++) { 
                for (int countB = 1; countB <= b; countB++) {
                    multArray[countA - 1][countB - 1] = countA * countB;
                }
    
            }
            System.out.print("Creating .");
            delay(1000);
            System.out.print(" .");
            delay(1000);
            System.out.print(" .");
            delay(1000);
            System.out.println(newLine + "Done.");
            return multArray;
    
        }
    
        public static void print() {
            **//This is where I need to print multArray created above is it possible?**
        }
    
        public static void delay(int millis) {
            try {
                Thread.sleep(millis);
            } 
            catch (InterruptedException exp) {  
            }
        }
    }
    

    到目前为止,我发现这是最好和最快的VBA解决方案,可以从已关闭的工作簿(带变量)获取INSTANT中的数据,而无需打开它们。