Excel 选择特定图纸并保存在新文件中
我有一个excel文件,里面有240栋建筑的信息,1、2、3、4[…]和239240各一张。然后是用于新信息1(1)、1(2)、1(3)等的其他图纸。是否可以创建一个vba,选择1(*),并在一个文件中仅复制建筑1的图纸,依此类推所有240个建筑 编辑。我知道这是不允许的,但是伪代码应该是这样的smthExcel 选择特定图纸并保存在新文件中,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 我只
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)|
您可以看到非标准或超出范围的工作表