mikewolf2k
发表于 2018-8-23 16:53:02
qwh923820 发表于 2018-8-23 16:40
是的,先如果某行某列全空,是被删除掉的。如果要精准判断,后续可以加入线条的坐标进行定位判断。
本程 ...
无论怎么判断,总能找出破绽,做不出通用的。只要能胜任要处理的表格就可以了。现在已经很不错了。
蓝盾设计
发表于 2018-8-26 23:54:54
好好学习楼主
VBALISPER
发表于 2018-8-27 17:17:17
还有合并单元格需要考虑一下.
664571221
发表于 2018-9-7 20:57:02
你好怎么用啊,这个是vb吗
sxz4494
发表于 2018-9-12 11:26:34
qwh923820 发表于 2018-8-23 14:14
1.制定要转换的CAD表格位置,如果你想改成插件用,可以采用getpoint方法(就是注释掉的),如果你是写在 ...
如果采用getpoint方法,程序提示编译错误:不能给数组赋值是哪儿有问题吗,我在同一个文件里面其他的程序用getpoint则没有问题
qwh923820
发表于 2018-9-14 09:14:37
sxz4494 发表于 2018-9-12 11:26
如果采用getpoint方法,程序提示编译错误:不能给数组赋值是哪儿有问题吗,我在同一个文件里面其他的 ...
pt1,pt2原本定义的是数组,必须要注释掉,改成变体型vairant
如图修改:
kosan
发表于 2018-9-14 11:14:48
qwh923820 发表于 2018-9-14 09:14
pt1,pt2原本定义的是数组,必须要注释掉,改成变体型vairant
如图修改:
麻烦楼主看一下这个表,转出来有点错位。谢谢!
qwh923820
发表于 2018-9-17 08:58:09
kosan 发表于 2018-9-14 11:14
麻烦楼主看一下这个表,转出来有点错位。谢谢!
原本程序有个BUG,现在已经改好了,新代码你再试试看吧!!
Option Explicit
Public Sub Cad表格转Excel()
Dim objEntArr() As Object, i As Long
Dim objSset As AcadSelectionSet
Dim y As AcadSelectionSet
'Dim pt1(2) As Double, pt2(2) As Double
Dim p, j, A(1 To 990, 1 To 7), B(), C(), D(), n, m, k, ky, kx, m1, m2, na$
Dim E()
'pt1,pt2是表格的位置,左下,右上
'pt1(0) = -1500
'pt1(1) = -1500
'pt1(2) = 0
'pt2(0) = 43200
'pt2(1) = 43200
'pt2(2) = 0
Dim pt1, pt2
pt1 = ThisDrawing.Utility.GetPoint(, "Enter a point: ")
pt2 = ThisDrawing.Utility.GetPoint(, "Enter a point: ")
na = "QQQ"
k = 0
On Error Resume Next
If Not IsNull(ThisDrawing.SelectionSets.Item(na)) Then
Set y = ThisDrawing.SelectionSets.Item(na)
y.Delete
End If
Set y = ThisDrawing.SelectionSets.Add(na)
Dim gpCode(0) As Integer
Dim dataValue(0) As Variant
gpCode(0) = 0
dataValue(0) = "text,mtext"
Dim groupCode As Variant, dataCode As Variant
groupCode = gpCode
dataCode = dataValue
' pt1 = ThisDrawing.Utility.GetPoint(, "Enter a point: ")
' pt2 = ThisDrawing.Utility.GetPoint(, "Enter a point: ")
y.Select acSelectionSetCrossing, pt1, pt2, groupCode, dataCode
For i = 0 To y.Count - 1
A(i + 1, 1) = i
A(i + 1, 2) = y.Item(i).TextString
p = y.Item(i).InsertionPoint
k = IIf(y.Item(i).Height - k > 0, y.Item(i).Height, k) 'k是过滤间隙
y.Item(i).GetBoundingBox m1, m2
A(i + 1, 3) = p(0)
A(i + 1, 4) = p(1)
A(i + 1, 5) = (m1(0) + m2(0)) / 2 '文字中心坐标
A(i + 1, 6) = (m2(0) - m1(0)) / 2 '文字长度的一半
A(i + 1, 7) = (p(0) + A(i + 1, 5)) / 2 '插入点与文字中心坐标的中心点
A(i + 1, 5) = A(i + 1, 5) + A(i + 1, 6) / 2.5 '文字中心坐标往右偏
Next i
y.Delete
' Stop
'k = 50 'k是过滤间隙
ky = k
kx = k * 1.2
B = 过滤数组(A, 4, ky)
C = 过滤数组(A, 7, kx)
'Stop
ReDim D(1 To UBound(B) + 1, 1 To UBound(C) + 1)
For i = 1 To UBound(A)
If A(i, 2) = "" Then Exit For
For n = 0 To UBound(B)
'行的位置
If Abs(B(n) - A(i, 4)) < ky Then
Exit For
End If
Next n
For m = 0 To UBound(C)
'列的位置
If Abs(C(m) - A(i, 7)) < kx Then
Exit For
End If
Next m
If D(UBound(B) + 1 - n, 1 + m) = "" Then
D(UBound(B) + 1 - n, 1 + m) = i
Else
D(UBound(B) + 1 - n, 1 + m) = i & "~~" & D(UBound(B) + 1 - n, 1 + m)
End If
Next i
E = 整合数组列(A, D, 1)
E = 替换文字内容(A, E)
Dim exlh As Object
Set exlh = GetObject(, "excel.application")
With exlh
.workbooks(1).worksheets(1).Select
.cells.Select
.Selection.Clear
'.cells(1, 1).resize(990, 7) = A
'.cells(1, 9).resize(UBound(B) + 1, UBound(C) + 1) = D
.cells(1, 1).resize(UBound(E), UBound(E, 2)) = E
End With
End Sub
Function 过滤数组(ByVal A, ByVal n, ByVal k) As Variant
'A是数组,n是过滤的列,k是过滤的间隙
Dim B(), i, j, p, m
j = 0
ReDim B(0)
B(0) = A(1, n)
For i = 2 To UBound(A)
m = 0
If A(i, n) = "" Then Exit For
For p = 0 To j
If Abs(A(i, n) - B(p)) < k Then
m = 1
Exit For
End If
Next p
If m = 0 Then
j = j + 1
ReDim Preserve B(j)
B(j) = A(i, n)
End If
Next i
过滤数组 = 冒泡排序(B)
End Function
Function 冒泡排序(ByVal A) As Variant
'从小到大
Dim i, j, n
For i = 0 To UBound(A) - 1
For j = 0 To UBound(A) - 1 - i
If A(j) > A(j + 1) Then
n = A(j + 1)
A(j + 1) = A(j)
A(j) = n
End If
Next j
Next i
冒泡排序 = A
End Function
Function 整合数组列(ByVal A, ByVal D, ByVal n)
'以中心点和插入点间距为判断
'当相连两列n列与n+1列比较,n+1列文字插入点或中心点在n列的插入点与中心点之间时,合并
'n列的插入点与中心点之间距离取该列最大值
Dim i, j, L, p, q, x1, x2, y, B, x3, x4
Dim C()
L = 0
If n >= UBound(D, 2) Then
整合数组列 = D
Exit Function
End If
'n列的插入点与中心点之间距离取该列最大值L及插入点和中心点X坐标
For i = 1 To UBound(D)
If D(i, n) <> "" Then
If InStr(D(i, n), "~~") > 0 Then
B = Split(D(i, n), "~~")
For j = 0 To UBound(B)
y = Abs(A(B(j), 5) - A(B(j), 3))
If L < y Then
L = y
x1 = A(B(j), 3): x2 = A(B(j), 5)
End If
Next j
Erase B
Else
y = Abs(A(D(i, n), 5) - A(D(i, n), 3))
If L < y Then
L = y
x1 = A(D(i, n), 3): x2 = A(D(i, n), 5)
End If
End If
End If
Next i
'Stop
For i = 1 To UBound(D)
p = 0
If D(i, n + 1) <> "" Then
'Stop
If InStr(D(i, n + 1), "~~") > 0 Then
B = Split(D(i, n + 1), "~~")
For j = 0 To UBound(B)
x3 = A(B(j), 3): x4 = A(B(j), 5)
If IIf(x3 > x4, x4, x3) < IIf(x2 > x1, x2, x1) Then
p = 1
Exit For
End If
Next j
Erase B
Else
x3 = A(D(i, n + 1), 3): x4 = A(D(i, n + 1), 5)
If IIf(x3 > x4, x4, x3) < IIf(x2 > x1, x2, x1) Then p = 1
End If
If p = 1 Then
If D(i, n) = "" Then
D(i, n) = D(i, n + 1)
Else
D(i, n) = 纵向排列同一单元格文字(A, D(i, n) & "~~" & D(i, n + 1))
End If
D(i, n + 1) = ""
End If
End If
Next i
'Call excelqingchu(n)
'Call EXCEL输出(D)
C = 去除数组第N列空列(D, n + 1)
If UBound(C, 2) < UBound(D, 2) Then n = n - 1
'If n = 10 Then Stop
'Call EXCEL输出(C)
'Stop
整合数组列 = 整合数组列(A, C, n + 1)
End Function
Function 纵向排列同一单元格文字(ByVal A, ByVal t)
Dim B, i, j, k, C(), D(), E()
B = Split(t, "~~")
k = ""
ReDim C(UBound(B))
ReDim E(0 To UBound(B), 1 To 2)
For i = 0 To UBound(C)
C(i) = A(B(i), 4)
E(i, 1) = C(i)
E(i, 2) = B(i)
Next i
Erase B
D = 冒泡排序(C)
For i = UBound(D) To 0 Step -1
For j = 0 To UBound(D)
If Abs(D(i) - E(j, 1)) < 0.001 Then
If k = "" Then
k = E(j, 2)
Else
k = k & "~~" & E(j, 2)
End If
E(j, 1) = -1235.778
End If
Next j
Next i
纵向排列同一单元格文字 = k
End Function
Function 去除数组第N列空列(ByVal D, ByVal n)
Dim B(), i, j
For i = 1 To UBound(D)
If D(i, n) <> "" Then 去除数组第N列空列 = D: Exit Function
Next i
ReDim C(1 To UBound(D), 1 To UBound(D, 2) - 1)
For i = 1 To UBound(D)
For j = 1 To UBound(C, 2)
If j < n Then
C(i, j) = D(i, j)
ElseIf j >= n Then
C(i, j) = D(i, j + 1)
End If
Next j
Next i
去除数组第N列空列 = C
End Function
Function 替换文字内容(ByVal A, ByVal D)
Dim B, i, j, k, n, m
For i = 1 To UBound(D)
For j = 1 To UBound(D, 2)
m = ""
If D(i, j) <> "" Then
If InStr(D(i, j), "~~") > 0 Then
B = Split(D(i, j), "~~")
For k = 0 To UBound(B)
If m = "" Then m = A(B(k), 2) Else m = m & Chr(10) & A(B(k), 2)
Next k
Erase B
Else
m = A(D(i, j), 2)
End If
D(i, j) = m
End If
Next j
Next i
替换文字内容 = D
End Function
Sub EXCEL输出(ByVal D)
Dim i, j, r
i = UBound(D)
j = UBound(D, 2)
Dim exlh As Object
Set exlh = GetObject(, "excel.application")
With exlh
.workbooks(1).worksheets(1).Select
r = .cells(9999, 1).End(3).row + 2
.cells(r, 1).resize(i, j) = D
End With
End Sub
Sub excelqingchu(n)
Dim exlh As Object
Set exlh = GetObject(, "excel.application")
With exlh
.workbooks(1).worksheets(1).Select
.cells.Select
.Selection.Clear
End With
End Sub
qwh923820
发表于 2018-9-17 09:39:33
已经改成新建一个sheet,放入其中了
Option Explicit
Public Sub Cad表格转Excel()
Dim objEntArr() As Object, i As Long
Dim objSset As AcadSelectionSet
Dim y As AcadSelectionSet
'Dim pt1(2) As Double, pt2(2) As Double
Dim p, j, A(1 To 990, 1 To 7), B(), C(), D(), n, m, k, ky, kx, m1, m2, na$
Dim E()
'pt1,pt2是表格的位置,左下,右上
'pt1(0) = -1500
'pt1(1) = -1500
'pt1(2) = 0
'pt2(0) = 43200
'pt2(1) = 43200
'pt2(2) = 0
Dim pt1, pt2
pt1 = ThisDrawing.Utility.GetPoint(, "Enter a point: ")
pt2 = ThisDrawing.Utility.GetPoint(, "Enter a point: ")
na = "QQQ"
k = 0
On Error Resume Next
If Not IsNull(ThisDrawing.SelectionSets.Item(na)) Then
Set y = ThisDrawing.SelectionSets.Item(na)
y.Delete
End If
Set y = ThisDrawing.SelectionSets.Add(na)
Dim gpCode(0) As Integer
Dim dataValue(0) As Variant
gpCode(0) = 0
dataValue(0) = "text,mtext"
Dim groupCode As Variant, dataCode As Variant
groupCode = gpCode
dataCode = dataValue
' pt1 = ThisDrawing.Utility.GetPoint(, "Enter a point: ")
' pt2 = ThisDrawing.Utility.GetPoint(, "Enter a point: ")
y.Select acSelectionSetCrossing, pt1, pt2, groupCode, dataCode
For i = 0 To y.Count - 1
A(i + 1, 1) = i
A(i + 1, 2) = y.Item(i).TextString
p = y.Item(i).InsertionPoint
k = IIf(y.Item(i).Height - k > 0, y.Item(i).Height, k) 'k是过滤间隙
y.Item(i).GetBoundingBox m1, m2
A(i + 1, 3) = p(0)
A(i + 1, 4) = p(1)
A(i + 1, 5) = (m1(0) + m2(0)) / 2 '文字中心坐标
A(i + 1, 6) = (m2(0) - m1(0)) / 2 '文字长度的一半
A(i + 1, 7) = (p(0) + A(i + 1, 5)) / 2 '插入点与文字中心坐标的中心点
A(i + 1, 5) = A(i + 1, 5) + A(i + 1, 6) / 2.5 '文字中心坐标往右偏
Next i
y.Delete
' Stop
'k = 50 'k是过滤间隙
ky = k
kx = k * 1.2
B = 过滤数组(A, 4, ky)
C = 过滤数组(A, 7, kx)
'Stop
ReDim D(1 To UBound(B) + 1, 1 To UBound(C) + 1)
For i = 1 To UBound(A)
If A(i, 2) = "" Then Exit For
For n = 0 To UBound(B)
'行的位置
If Abs(B(n) - A(i, 4)) < ky Then
Exit For
End If
Next n
For m = 0 To UBound(C)
'列的位置
If Abs(C(m) - A(i, 7)) < kx Then
Exit For
End If
Next m
If D(UBound(B) + 1 - n, 1 + m) = "" Then
D(UBound(B) + 1 - n, 1 + m) = i
Else
D(UBound(B) + 1 - n, 1 + m) = i & "~~" & D(UBound(B) + 1 - n, 1 + m)
End If
Next i
E = 整合数组列(A, D, 1)
E = 替换文字内容(A, E)
Call EXCEL输出(E)
'Dim exlh As Object
'Set exlh = GetObject(, "excel.application")
'With exlh
' .workbooks(1).worksheets(1).Select
' .cells.Select
' .Selection.Clear
' '.cells(1, 1).resize(990, 7) = A
' '.cells(1, 9).resize(UBound(B) + 1, UBound(C) + 1) = D
' .cells(1, 1).resize(UBound(E), UBound(E, 2)) = E
'
'End With
End Sub
Function 过滤数组(ByVal A, ByVal n, ByVal k) As Variant
'A是数组,n是过滤的列,k是过滤的间隙
Dim B(), i, j, p, m
j = 0
ReDim B(0)
B(0) = A(1, n)
For i = 2 To UBound(A)
m = 0
If A(i, n) = "" Then Exit For
For p = 0 To j
If Abs(A(i, n) - B(p)) < k Then
m = 1
Exit For
End If
Next p
If m = 0 Then
j = j + 1
ReDim Preserve B(j)
B(j) = A(i, n)
End If
Next i
过滤数组 = 冒泡排序(B)
End Function
Function 冒泡排序(ByVal A) As Variant
'从小到大
Dim i, j, n
For i = 0 To UBound(A) - 1
For j = 0 To UBound(A) - 1 - i
If A(j) > A(j + 1) Then
n = A(j + 1)
A(j + 1) = A(j)
A(j) = n
End If
Next j
Next i
冒泡排序 = A
End Function
Function 整合数组列(ByVal A, ByVal D, ByVal n)
'以中心点和插入点间距为判断
'当相连两列n列与n+1列比较,n+1列文字插入点或中心点在n列的插入点与中心点之间时,合并
'n列的插入点与中心点之间距离取该列最大值
Dim i, j, L, p, q, x1, x2, y, B, x3, x4
Dim C()
L = 0
If n >= UBound(D, 2) Then
整合数组列 = D
Exit Function
End If
'n列的插入点与中心点之间距离取该列最大值L及插入点和中心点X坐标
For i = 1 To UBound(D)
If D(i, n) <> "" Then
If InStr(D(i, n), "~~") > 0 Then
B = Split(D(i, n), "~~")
For j = 0 To UBound(B)
y = Abs(A(B(j), 5) - A(B(j), 3))
If L < y Then
L = y
x1 = A(B(j), 3): x2 = A(B(j), 5)
End If
Next j
Erase B
Else
y = Abs(A(D(i, n), 5) - A(D(i, n), 3))
If L < y Then
L = y
x1 = A(D(i, n), 3): x2 = A(D(i, n), 5)
End If
End If
End If
Next i
'Stop
For i = 1 To UBound(D)
p = 0
If D(i, n + 1) <> "" Then
'Stop
If InStr(D(i, n + 1), "~~") > 0 Then
B = Split(D(i, n + 1), "~~")
For j = 0 To UBound(B)
x3 = A(B(j), 3): x4 = A(B(j), 5)
If IIf(x3 > x4, x4, x3) < IIf(x2 > x1, x2, x1) Then
p = 1
Exit For
End If
Next j
Erase B
Else
x3 = A(D(i, n + 1), 3): x4 = A(D(i, n + 1), 5)
If IIf(x3 > x4, x4, x3) < IIf(x2 > x1, x2, x1) Then p = 1
End If
If p = 1 Then
If D(i, n) = "" Then
D(i, n) = D(i, n + 1)
Else
D(i, n) = 纵向排列同一单元格文字(A, D(i, n) & "~~" & D(i, n + 1))
End If
D(i, n + 1) = ""
End If
End If
Next i
'Call excelqingchu(n)
'Call EXCEL输出(D)
C = 去除数组第N列空列(D, n + 1)
If UBound(C, 2) < UBound(D, 2) Then n = n - 1
'If n = 10 Then Stop
'Call EXCEL输出(C)
'Stop
整合数组列 = 整合数组列(A, C, n + 1)
End Function
Function 纵向排列同一单元格文字(ByVal A, ByVal t)
Dim B, i, j, k, C(), D(), E()
B = Split(t, "~~")
k = ""
ReDim C(UBound(B))
ReDim E(0 To UBound(B), 1 To 2)
For i = 0 To UBound(C)
C(i) = A(B(i), 4)
E(i, 1) = C(i)
E(i, 2) = B(i)
Next i
Erase B
D = 冒泡排序(C)
For i = UBound(D) To 0 Step -1
For j = 0 To UBound(D)
If Abs(D(i) - E(j, 1)) < 0.001 Then
If k = "" Then
k = E(j, 2)
Else
k = k & "~~" & E(j, 2)
End If
E(j, 1) = -1235.778
End If
Next j
Next i
纵向排列同一单元格文字 = k
End Function
Function 去除数组第N列空列(ByVal D, ByVal n)
Dim B(), i, j
For i = 1 To UBound(D)
If D(i, n) <> "" Then 去除数组第N列空列 = D: Exit Function
Next i
ReDim C(1 To UBound(D), 1 To UBound(D, 2) - 1)
For i = 1 To UBound(D)
For j = 1 To UBound(C, 2)
If j < n Then
C(i, j) = D(i, j)
ElseIf j >= n Then
C(i, j) = D(i, j + 1)
End If
Next j
Next i
去除数组第N列空列 = C
End Function
Function 替换文字内容(ByVal A, ByVal D)
Dim B, i, j, k, n, m
For i = 1 To UBound(D)
For j = 1 To UBound(D, 2)
m = ""
If D(i, j) <> "" Then
If InStr(D(i, j), "~~") > 0 Then
B = Split(D(i, j), "~~")
For k = 0 To UBound(B)
If m = "" Then m = A(B(k), 2) Else m = m & Chr(10) & A(B(k), 2)
Next k
Erase B
Else
m = A(D(i, j), 2)
End If
D(i, j) = m
End If
Next j
Next i
替换文字内容 = D
End Function
Sub EXCEL输出(ByVal D)
Dim i, j, r
i = UBound(D)
j = UBound(D, 2)
Dim exlh As Object
Set exlh = GetObject(, "excel.application")
With exlh
.workbooks(1).worksheets(1).Select
.Sheets.Add
'r = .cells(9999, 1).End(3).row + 2
'If r < 3 Then r = 1
r = 1
.cells(r, 1).resize(i, j) = D
.Range(.cells(1, 1), .cells(i, j)).Select
.Selection.VerticalAlignment = 2
.Selection.HorizontalAlignment = 3
.Selection.Borders().LineStyle = 1
End With
End Sub
Sub excelqingchu(n)
Dim exlh As Object
Set exlh = GetObject(, "excel.application")
With exlh
.workbooks(1).worksheets(1).Select
.cells.Select
.Selection.Clear
End With
End Sub
kosan
发表于 2018-9-17 09:57:10
本帖最后由 kosan 于 2018-9-17 09:58 编辑
qwh923820 发表于 2018-9-17 09:39
已经改成新建一个sheet,放入其中了
提取的数据不完整?上面的那个CAD表格文件,多粘贴几遍,列数弄多一点。比如100列,但是EXCEL中输出的只有二三十列,而且每次列数不尽相同。