在Excel For Loop中连接以生成命令的批处理文件

时间:2014-10-15 03:09:48

标签: excel vba excel-vba batch-file icacls

请考虑以下情况:我的客户端在服务器上有两个网络共享。每个共享包含代表每个项目的相同文件夹列表(一个用于当前数据,另一个用于存档数据)。每个项目文件夹都包含一组匹配的文件夹和子文件夹,需要分配单独的权限。当然,项目会不时添加和删除。

我想在Excel中维护一个项目列表,以及需要为每个项目文件夹及其所有子文件夹设置的权限列表。我的想法是每行在Excel中布置一个命令,每行代表一个子文件夹。然后使用for循环复制这些命令,将共享文件夹和项目文件夹添加到目录路径。输出将是一个批处理文件,我可以在任何时候运行需要更改或更新的权限。

编辑: 我从未在Excel中使用VBA,在搜索之后,我似乎无法找到如何在for循环中使用变量来更改工作表中的哪些单元格被引用。自从我编写任何程序以来已经有一段时间了,但是当我用C编程时,我记得能够使用for循环中的变量来引用列表/表中的单元格。当for循环经历迭代时,变量将计数改变它们引用的列表中的哪个单元格。用Excel术语表示我希望每个for循环中的变量都是行号,我将静态分配列字母,因为每次迭代都不会改变。

每次for循环运行时,我都希望它将一系列单元格连接成一个文本字符串,输出到文本文件的新行。连接将在每个循环期间将一些保持相同的单元连接在一起,并且随着变量递增而变化的其他单元。例如,我想连接单元格A1,B1,Ci,Dj,E1,Fk,其中i,j和k表示用于计算每个for循环的迭代的整数的数值。

您能告诉我使用可变单元格分配实现串联的正确语法是什么吗?这是我的代码的摘录。

For i = 2 To numberOfSharedFolders

        'Loops for every subfolder (project folder) in the shared folder that needs permissions set
        For j = 2 To numberOfSubfolders1

            'Loops for every entry of permissions on final folders
            For k = 2 To numberOfSubfolders2

                concatenatedDataString = ActiveSheet.Range("A1") & ActiveSheet.Range("B1") & ActiveSheet.Range("C"i) & ActiveSheet.Range("D"j)
                Write #1, concatenatedDataString

            Next k
        Next j
    Next i

2 个答案:

答案 0 :(得分:1)

.B3不是ActiveSheet对象的方法或属性。

我怀疑你打算ActiveSheet.Range("B3")

可能还有其他错误,实际上接下来的两行可能会引发相同的错误。

除此之外可能还有更多内容,例如请注意此语句中的拼写错误会引发424 Object Required错误(因为Appleication不是对象,因此将其视为未定义/未声明的变量,为空值):

filePath = Appleication.DefaultFilePath & "icacls Commands.bat"

您可以在每个模块的顶部使用Option Explicit来帮助规范拼写错误(这会引发任何未定义变量的编译错误,并且拼写错误被解释为未定义的变量。

对于你的其余问题(实际上你要问的是6个相当广泛的问题)我会尽量回答,但不会在这里的评论中真正接受长期的Q& A或讨论。如果您有具体问题,应单独询问(在您完成搜索/故障排除等的尽职调查之后)。

  

我应该如何在for循环中连接?

不知道你的意思。您通过在现有字符串中附加一些值来循环连接。使用&运算符代替+运算符,因为后者可能会被非字符串数据混淆(即"hello" & 1不会引发错误,但"hello" +1会引起不匹配)。

Dim i as Integer
Dim s as String
s = "some words"
For i = 1 to 10

    s = s & some_other_variable

Next

实际上,你的代码并没有连接任何只是添加整数的字符串:

concatenatedDataSting = i + j + k

ijk都是整数数据。这不是创建一个字符串(如果是,它是一个强制/隐含的字符串,表示该操作的数字和)。

  

有没有更好的方法来设置for循环的变量?目前我有一个单元格,使用countif(D:D,“*”)总计每列的大小,并将其分配给变量。

WHat变量?我在上面的代码中没有看到任何列D或CountIf函数的引用。

  

在表格中引用数据的最佳方法是什么?范围()? currentsheet.range()?

这取决于“表格中的数据”的含义。不清楚,太宽泛无法回答。

  

如何执行此程序?通过在开发者控制台中单击播放?

从“开发人员功能区”,“宏”菜单中,选择“ThisWorkbook”中的宏(或其所在的任何一本书)。然后跑。或者从控制台/ VBE,按F5或“运行”按钮。

  

我如何知道文本文件的最终位置?默认位置是我的文档吗?

一旦你纠正错字,它就会在这里结束:

Application.DefaultFilePath

您可以执行此操作以查看其位置:MsgBox Application.DefaultFilePath

答案 1 :(得分:0)

我得到了这一切。我的代码如下。阅读原始问题,了解更多信息。

Sub Sheet1Compile()

'Create variables used in for loops
Dim numberOfSharedFolders As Integer
Dim numberOfSubfolders1 As Integer
Dim numberOfSubfolders2 As Integer
Dim i As Integer
Dim j As Integer
Dim k As Integer

'Set values of variables to the number of rows in each column.
'Note that the value includes the column titles in row 1
numberOfSharedFolders = ActiveSheet.Range("B2")
numberOfSubfolders1 = ActiveSheet.Range("B3")
numberOfSubfolders2 = ActiveSheet.Range("B4")


'Create text file to output of data from for loop
Dim filePath As String
filePath = Application.DefaultFilePath & "\icacls Commands.txt"
Open filePath For Output As #1


'Loops for every row in the first mentioned column (except the first row which contains column labels)
'Initializing to 2 instead of 1 so that the loop will skip the first row which is just column labels. Not setting it to 0 since there is no row 0
For i = 2 To numberOfSharedFolders

    'Loops for every row in the second mentioned column (except the first row which contains column labels)
    For j = 2 To numberOfSubfolders1

        'Loops for every row in the third mentioned column (except the first row which contains column labels)
        For k = 2 To numberOfSubfolders2

            'Print the concatendated text to the output file. Print is used instead of "write" so that it doesn't produce unwanted quotation marks.
            Print #1, ActiveSheet.Cells(2, 3) & ActiveSheet.Cells(i, 4) & ActiveSheet.Cells(j, 5) & ActiveSheet.Cells(1, 6) & ActiveSheet.Cells(k, 7) & ActiveSheet.Cells(1, 8) & ActiveSheet.Cells(k, 9)

        Next k
    Next j
Next i

Close #1

End Sub