|
本帖最后由 usbusb 于 2015-7-30 16:11 编辑
你好,大侠
把转存的代码部分提高了一下效率,试了一下一个10MB的包,效果很明显
Private Declare Sub GlobalUnlock Lib "kernel32" (ByVal hMem As Long)
Private Declare Sub CloseClipboard Lib "user32" ()
Private Declare Sub RtlMoveMemory Lib "kernel32" (Destination As Any, ByVal Source As Long, ByVal Length As Long)
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, ByVal Source As Long, ByVal Length As Long)
Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function RegisterClipboardFormat Lib "user32" Alias "RegisterClipboardFormatA" (ByVal lpString As String) As Long
Private Declare Function EmptyClipboard Lib "user32" () As Long
Public Sub btn_Export_Click()
GetPackagedFile ThisWorkbook.Sheets(1).OLEObjects(1), ThisWorkbook.Path & "\Package.zip"
End Sub
'其中 obj 为要导出文件的包对象,FileName 为输出文件名
Private Function GetPackagedFile(obj As OLEObject, FileName As String) As Boolean
GetPackagedFile = False
If obj Is Nothing Then Exit Function
If obj.progID <> "Package" Then Exit Function
Dim HandleC As Long, pMem As Long, FileSize As Long, fn As Long, i As Long, b As Byte
Dim nClipsize As Long, bytData() As Byte, lHeader As Variant
On Error Resume Next
Kill FileName
obj.Copy
If OpenClipboard(0) Then
HandleC = GetClipboardData(RegisterClipboardFormat("Native" & Chr$(0)))
If HandleC Then
nClipsize = GlobalSize(HandleC)
pMem = GlobalLock(HandleC)
If pMem Then
ReDim bytData(0 To nClipsize) As Byte
' Cut the Header "02 00 00 00" After Second Execution
CopyMemory bytData(0), ByVal pMem, nClipsize
If (bytData(0) = 2) And (bytData(1) = 0) And (bytData(2) = 0) And (bytData(3) = 0) Then
pMem = pMem + 4
CopyMemory bytData(0), bytData(pMem), nClipsize - 4
End If
If GetBytes(pMem, 2) = 0 Then
pMem = pMem + 6
Do While GetBytes(pMem, 1) <> 0: Loop
FileSize = GetBytes(pMem, 4)
CopyMemory bytData(0), ByVal pMem, FileSize
fn = FreeFile
Err = 0
Open FileName For Binary Lock Write As fn
If Err = 0 Then
'For i = 1 To FileSize
' b = GetBytes(pMem, 1)
' Put fn, , b
'Next
CopyMemory bytData(0), bytData(pMem), FileSize
Put fn, , bytData
Close fn
GetPackagedFile = True
End If
Else
MsgBox "包对象内不能有图标和标签名称,即左边内容应该全部为空, 而右边必须包含一个文件"
End If
End If
GlobalUnlock HandleC
End If
EmptyClipboard ' 清理剪贴板,解决包内文件很大的情况下退出Excel时响应慢的问题
CloseClipboard
End If
End Function
Private Function GetBytes(ByRef pMem As Long, ByVal n As Integer) As Long
GetBytes = 0
RtlMoveMemory GetBytes, ByVal pMem, n
pMem = pMem + n
End Function
|
|