Excel 选择特定图纸并保存在新文件中

Excel 选择特定图纸并保存在新文件中,excel,vba,Excel,Vba,我有一个excel文件,里面有240栋建筑的信息,1、2、3、4[…]和239240各一张。然后是用于新信息1(1)、1(2)、1(3)等的其他图纸。是否可以创建一个vba,选择1(*),并在一个文件中仅复制建筑1的图纸,依此类推所有240个建筑 编辑。我知道这是不允许的,但是伪代码应该是这样的smth for i=1..240 Pattern = "([i]\s\(\d\))" ' Sheet name 1 (1), 1 (2) etc copy in new file end 我只

我有一个excel文件,里面有240栋建筑的信息,1、2、3、4[…]和239240各一张。然后是用于新信息1(1)、1(2)、1(3)等的其他图纸。是否可以创建一个vba,选择1(*),并在一个文件中仅复制建筑1的图纸,依此类推所有240个建筑

编辑。我知道这是不允许的,但是伪代码应该是这样的smth

for i=1..240
  Pattern = "([i]\s\(\d\))" ' Sheet name 1 (1), 1 (2) etc
  copy in new file
end
我只是对vba不够熟悉

图纸的名称如下所示:

1, 3, 5, 4, 25, 34, 87, 95, 110, 125, 3 (1), 4 (1), 110 (1), 3 (2), 110 (2), 110 (3)
1, 1 (1), 1 (2), 1 (3)
2
3 (1)
110, 110 (1), 110 (2)
...
我需要像这样对他们进行分组:

1, 3, 5, 4, 25, 34, 87, 95, 110, 125, 3 (1), 4 (1), 110 (1), 3 (2), 110 (2), 110 (3)
1, 1 (1), 1 (2), 1 (3)
2
3 (1)
110, 110 (1), 110 (2)
...

最初的命名语法是这样的:#buildingNum[1-240]space(#update)

这应该满足您的需要。工作表的名称为1,2,3。。。图纸名称将为1(1)、1(2)、2(1)。。。如果要将工作簿命名为其他名称,只需更改密钥名称

Option Explicit

Sub test()
    Dim sheetvar As Variant
    Dim mainsheet As String
    Dim subsheets As String
    Dim sheetdict As Object
    Dim currentbook As Workbook

    Set sheetdict = CreateObject("Scripting.Dictionary")
    Set currentbook = ActiveWorkbook

    For Each sheetvar In currentbook.Sheets
        If InStr(1, sheetvar.Name, "(") Then
            mainsheet = trim(Split(sheetvar.Name, "(")(0))
        Else
            mainsheet = sheetvar.Name 'Get Name
        End If
        If Not sheetdict.exists(mainsheet) Then 'Make Dictionary Key
            subsheets = sheetvar.Name
            sheetdict.Add mainsheet, subsheets
        Else
            subsheets = sheetdict(mainsheet) & "|" & sheetvar.Name
            sheetdict(mainsheet) = subsheets
        End If
    Next sheetvar

    Dim key As Variant
    Dim isheet As Variant
    Dim newbook As Workbook
    Application.DisplayAlerts = False 'Might not want this if you want to see whats going on
    For Each key In sheetdict
        Set newbook = Workbooks.Add
        newbook.SaveAs key & ".xlsx"
        For Each isheet In Split(sheetdict(key), "|")
            If Not isheet Like "" Then
                currentbook.Sheets(isheet).Copy before:=newbook.Sheets("Sheet1")
            End If
        Next isheet
        If newbook.Sheets.Count > 1 Then 'Dodge error if there is only 1 sheet
            newbook.Sheets("Sheet1").Delete
        End If
    newbook.save
    newbook.close
    Next key
    Application.DisplayAlerts = True

End Sub

这应该是你想要的。工作表的名称为1,2,3。。。图纸名称将为1(1)、1(2)、2(1)。。。如果要将工作簿命名为其他名称,只需更改密钥名称

Option Explicit

Sub test()
    Dim sheetvar As Variant
    Dim mainsheet As String
    Dim subsheets As String
    Dim sheetdict As Object
    Dim currentbook As Workbook

    Set sheetdict = CreateObject("Scripting.Dictionary")
    Set currentbook = ActiveWorkbook

    For Each sheetvar In currentbook.Sheets
        If InStr(1, sheetvar.Name, "(") Then
            mainsheet = trim(Split(sheetvar.Name, "(")(0))
        Else
            mainsheet = sheetvar.Name 'Get Name
        End If
        If Not sheetdict.exists(mainsheet) Then 'Make Dictionary Key
            subsheets = sheetvar.Name
            sheetdict.Add mainsheet, subsheets
        Else
            subsheets = sheetdict(mainsheet) & "|" & sheetvar.Name
            sheetdict(mainsheet) = subsheets
        End If
    Next sheetvar

    Dim key As Variant
    Dim isheet As Variant
    Dim newbook As Workbook
    Application.DisplayAlerts = False 'Might not want this if you want to see whats going on
    For Each key In sheetdict
        Set newbook = Workbooks.Add
        newbook.SaveAs key & ".xlsx"
        For Each isheet In Split(sheetdict(key), "|")
            If Not isheet Like "" Then
                currentbook.Sheets(isheet).Copy before:=newbook.Sheets("Sheet1")
            End If
        Next isheet
        If newbook.Sheets.Count > 1 Then 'Dodge error if there is only 1 sheet
            newbook.Sheets("Sheet1").Delete
        End If
    newbook.save
    newbook.close
    Next key
    Application.DisplayAlerts = True

End Sub

我不会一次就完成这项任务。我见过这样的任务,其中有些内容没有复制到新位置或复制到错误的位置。在发现错误之前可能需要几个月的时间,修复错误造成的任何损坏可能代价高昂,也可能是不可能的

下面是我的解决方案的第一部分。它使用一系列集合,最多可容纳250栋建筑。您认为有240座建筑,但如果有更多,请将
将WSHTGRP(0到250)作为集合修改为集合
。它对每个工作表进行分类,并将其名称放在其中一个集合中。如果名称与您的格式不匹配,则将其置于
WshtGrps(0)
中。对所有工作表进行分类后,集合将输出到桌面文件“worksheets.txt”。对于我的测试工作簿,输出为:

Grp|Worksheets -->
  0|Other1|Other2|1.2|251|
  1|1|1 (2)|1 (3)|
  2|2|2 (2)|
  3|3|3 (2)|3 (3)|3 (4)|
  4|4|4 (2)|
  5|5|
 10|10|
 11|11|
 12|12|
 20|20|
 30|30|
100|100|
200|200|
250|250|250 (2)|
您可以看到名称不标准或超出范围的工作表显示在顶部。我们希望您没有WSHTGRP(0)的行,但是,如果您有,您将需要决定如何处理它们

Option Explicit
Sub SplitWorkbook()

  Dim InxM As Long
  Dim InxW As Long
  Dim Line As String
  Dim NumFile As Long
  Dim NumWsht As Double
  Dim Path As String
  Dim WshtGrps(0 To 250) As Collection

  ' Initialise all the collections
  For InxW = LBound(WshtGrps) To UBound(WshtGrps)
    Set WshtGrps(InxW) = New Collection
  Next

  ' Add the name of all worksheets with integer name N to
  ' WshtGrps(N).  If the name N is not an integer or N is
  ' greater than UBound(WshtGrps) add the name to WshtGrps(0).
  For InxW = 1 To Worksheets.Count
    ' Val() skips any spaces then extracts digits up to the end of the
    ' string or until it reaches a character is does not recognise as
    ' part of a number. It returns zero if no digits are found.
    NumWsht = Val(Worksheets(InxW).Name)
    If NumWsht >= 1 And NumWsht <= UBound(WshtGrps) And CInt(NumWsht) = NumWsht Then
      WshtGrps(NumWsht).Add Worksheets(InxW).Name
    Else
      'NumWsht is out of range or not a integer
      WshtGrps(0).Add Worksheets(InxW).Name
    End If
  Next

  ' Output the worksheet groups to desktop file "Worksheets,txt"
  Path = CreateObject("WScript.Shell").specialfolders("Desktop") & "\Worksheets.txt"
  NumFile = FreeFile
  Open Path For Output As #NumFile
  Print #1, "Grp|Worksheets -->"
  For InxW = LBound(WshtGrps) To UBound(WshtGrps)
    If WshtGrps(InxW).Count > 0 Then
      Line = PadL(InxW, 3)
      For InxM = 1 To WshtGrps(InxW).Count
        Line = Line & "|" & WshtGrps(InxW)(InxM)
      Next
      Line = Line & "|"
      Print #1, Line
    End If
  Next
  Close #1

  ' ###### Delete when you are happy with the contents of Worksheets.txt
  Exit Sub

  Const WbkNameRoot As String = "Building "

  Dim InxW2 As Long
  Dim WbkNew As Workbook
  Dim WbkSrc As Workbook

  ' This assumes the worksheets to be copied are in the workbook
  ' containing this macro.  Amend if necessary.
  Set WbkSrc = ThisWorkbook

  ' Amend if you want the new workbooks to be somewhere else
  Path = WbkSrc.Path & "\"

  Application.ScreenUpdating = False

  For InxW = 1 To UBound(WshtGrps)
    If WshtGrps(InxW).Count > 0 Then
      Set WbkNew = Workbooks.Add

      With WbkNew
        ' Ensure all default worksheet have a name that does not
        ' match sheets to be copied in
        For InxW2 = 1 To .Worksheets.Count
          .Worksheets(InxW2).Name = "Other" & InxW2
        Next

        For InxM = 1 To WshtGrps(InxW).Count
          WbkSrc.Worksheets(WshtGrps(InxW)(InxM)).Copy After:=.Worksheets(.Worksheets.Count)
        Next

        For InxW2 = .Worksheets.Count To 1 Step -1
          If Left$(.Worksheets(InxW2).Name, 5) = "Other" Then
            Application.DisplayAlerts = False
            .Worksheets(InxW2).Delete
            Application.DisplayAlerts = True
          End If
        Next

        .SaveAs Filename:=Path & WbkNameRoot & PadL(InxW, 3, "0") & ".xlsx"
        .Close
      End With
    End If
  Next

  Application.ScreenUpdating = True

End Sub
Public Function PadL(ByVal Str As String, ByVal PadLen As Long, _
                     Optional ByVal PadChr As String = " ") As String

  ' Pad Str with leading PadChr to give a total length of PadLen
  ' If the length of Str exceeds PadLen, Str will not be truncated

  '   Sep15 Coded
  ' 20Dec15 Added code so overlength strings are not truncated
  ' 10Jun16 Added PadChr so could pad with characters other than space

  If Len(Str) >= PadLen Then
    ' Do not truncate over length strings
    PadL = Str
  Else
    PadL = Right$(String(PadLen, PadChr) & Str, PadLen)
  End If

End Function
选项显式
子工作簿()
暗淡如长
暗淡如长
将线变暗为字符串
暗淡的NumFile如长
双色暗黄色
将路径设置为字符串
将WSHTGRP(0到250)作为集合进行调整
'初始化所有集合
对于InxW=LBound(WshtGrps)到UBound(WshtGrps)
设置WshtGrps(InxW)=新集合
下一个
'将整数名为N的所有工作表的名称添加到
"WshtGrps(N)。如果名称N不是整数或N是
'大于UBound(WshtGrps)将名称添加到WshtGrps(0)。
对于InxW=1的工作表。计数
'Val()跳过任何空格,然后提取数字,直到
'字符串或直到它到达一个字符时才被识别为
“数字的一部分。如果找不到数字,则返回零。
NumWsht=Val(工作表(InxW).Name)
如果NumWsht>=1且NumWsht为0,则
直线=PadL(InxW,3)
对于InxM=1到WshtGrps(InxW)。计数
Line=Line&“|”和WshtGrps(InxW)(InxM)
下一个
直线=直线&“|”
打印第1行
如果结束
下一个
关闭#1
“#######如果您对Worksheets.txt的内容满意,请删除
出口接头
常量WbkNameRoot为String=“Building”
变暗InxW2的长度为
我们称之为工作簿
将WbkSrc设置为工作簿
'这假定要复制的工作表位于工作簿中
'包含此宏。如有必要,请修改。
设置WbkSrc=ThisWorkbook
'如果您希望新工作簿位于其他地方,请进行修改
Path=WbkSrc.Path&“\”
Application.ScreenUpdating=False
对于InxW=1至UBound(WshtGrps)
如果WshtGrps(InxW).Count>0,则
Set wbknowed=工作簿。添加
我知道
'确保所有默认工作表的名称都不是
'匹配要在中复制的工作表
对于InxW2=1到.Worksheets.Count
.工作表(InxW2).Name=“其他”&InxW2
下一个
对于InxM=1到WshtGrps(InxW)。计数
WbkSrc.Worksheets(WshtGrps(InxW)(InxM)).Copy-After:=.Worksheets(.Worksheets.Count)
下一个
对于InxW2=.Worksheets.Count,将其设置为1步骤-1
如果左$(.Worksheets(InxW2).Name,5)=“其他”,则
Application.DisplayAlerts=False
.工作表(InxW2).删除
Application.DisplayAlerts=True
如果结束
下一个
.SaveAs文件名:=Path&WbkNameRoot&PadL(InxW,3,“0”)和“.xlsx”
.结束
以
如果结束
下一个
Application.ScreenUpdating=True
端接头
公共函数PadL(ByVal Str作为字符串,ByVal PadLen作为长字符串_
可选ByVal PadChr As String=“”)作为字符串
'带前导PadChr的Pad Str表示PadLen的总长度
'如果Str的长度超过PadLen,Str将不会被截断
'9月15日编码
'20Dec15添加了代码,因此超长字符串不会被截断
'2016年6月10日添加了PadChr,因此可以使用空格以外的字符进行pad
如果Len(Str)>=PadLen,则
'不要截断超长字符串
PadL=Str
其他的
PadL=Right$(字符串(PadLen,PadChr)和Str,PadLen)
如果结束
端函数

我不会一次性尝试这项任务。我见过这样的任务,其中有些内容没有复制到新位置或复制到错误的位置。在发现错误之前可能需要几个月的时间,修复错误造成的任何损坏可能代价高昂,也可能是不可能的

下面是我的解决方案的第一部分。它使用一系列集合,最多可容纳250栋建筑。您认为有240座建筑,但如果有更多,请将
将WSHTGRP(0到250)作为集合修改为集合
。它对每个工作表进行分类,并将其名称放在其中一个集合中。如果名称与您的格式不匹配,则将其置于
WshtGrps(0)
中。对所有工作表进行分类后,集合将输出到桌面文件“worksheets.txt”。对于我的测试工作簿,输出为:

Grp|Worksheets -->
  0|Other1|Other2|1.2|251|
  1|1|1 (2)|1 (3)|
  2|2|2 (2)|
  3|3|3 (2)|3 (3)|3 (4)|
  4|4|4 (2)|
  5|5|
 10|10|
 11|11|
 12|12|
 20|20|
 30|30|
100|100|
200|200|
250|250|250 (2)|
您可以看到非标准或超出范围的工作表