久久―日本道色综合久久,亚洲欧美精品在线,狼狼色丁香久久婷婷综合五月,香蕉人人超,日本网站黄,国产在线观看不卡免费高清,无遮挡的毛片免费

2025年度未來(lái)銀行科技服務(wù)商TOP100
全世界各行各業(yè)聯(lián)合起來(lái),internet一定要實(shí)現(xiàn)!

創(chuàng)建ActiveX接口移植Excel工作表

2004-02-20 eNet&Ciweek

  Visual Basic 5.0中的簡(jiǎn)單ActiveX DLL,從而使用戶(hù)從Northwind數(shù)據(jù)庫(kù)中獲得一系列表單。只要選擇表單,就可以移植包含Access數(shù)據(jù)的Excel工作表。

  Excel工作表,該表包含菜單項(xiàng)的定制代碼,從而初始化ActiveX DLL??蓤?zhí)行程序,該程序可以發(fā)送上述工作簿,并可檢查公用資源中ActiveX DLL的新版本,如果發(fā)現(xiàn)存在新版本,則拷貝并注冊(cè)該DLL到用戶(hù)的機(jī)器。

  該方法的優(yōu)點(diǎn)

  我因?yàn)橐韵聨讉€(gè)原因而喜歡該方法。一旦ActiveX DLL編譯成功,它可以被任何ActiveX的兼容宿主程序調(diào)用,這意味著你能夠在Microsoft Word、Internet Explorer或者大量的應(yīng)用程序中使用它們。

  不同于 Excel中的VBA編碼,那些DLL一旦編譯成功就再也不能為用戶(hù)所修改,如果你想做一些與Excel相似的工作,就必須創(chuàng)建并發(fā)布相應(yīng)的附加項(xiàng)。正如前面討論的那樣,只要進(jìn)行簡(jiǎn)單的Visual Basic編程,用戶(hù)機(jī)器上的DLL就能夠輕易地被替換。這意味著一旦故障被發(fā)現(xiàn),或者新版本開(kāi)發(fā)成功,用戶(hù)就可以直接升級(jí),而再也不必經(jīng)受安裝整個(gè)應(yīng)用程序的痛苦。

  該方法的不足

  最大的不足是需要在兼容宿主程序上調(diào)用該ActiveX DLL,如果你要移植Excel工作表或Word文檔,那將不成問(wèn)題。如果你要在自己編制的可執(zhí)行程序或不可視的兼容宿主程序上調(diào)用該DLL,那么控制將變得比較困難,換句話說(shuō),此時(shí)采用標(biāo)準(zhǔn)的可執(zhí)行程序作為接口是不適合的,最好的方法是為另一個(gè)應(yīng)用程序提供接口。

  設(shè)計(jì)DLL

  為了創(chuàng)建接口,打開(kāi)Visual Basic并創(chuàng)建一個(gè)標(biāo)準(zhǔn)的可執(zhí)行項(xiàng)目,并將他存儲(chǔ)在你所選定的ExcelDLL文件夾中。為了加入Excel引用,點(diǎn)擊Project>References和Microsoft Excel 8.0 Object Library。雙擊Project Explorer中的缺省Form,并將之重新命名為frmMain,設(shè)定Form的標(biāo)題為Open Northwind Tables,并且增加具有下列屬性的控件:

  為了創(chuàng)建Access數(shù)據(jù)庫(kù)和Excel電子表格之間的接口,增加列表1的代碼到Form中。

  列表1:設(shè)計(jì)DLL,增加這些代碼到Form中以創(chuàng)建接口。

注釋?zhuān)篋eclare the new class
Dim mcls_clsExcelWork As New clsExcelWork

Private Sub cmdOpenTable_Click()
注釋?zhuān)篶all the CreateWorksheet method of the clsExcelWork
注釋?zhuān)篶lass.
mcls_clsExcelWork.CreateWorksheet
End Sub

Private Sub Form_Load()
注釋?zhuān)篶all the LoadListboxWithTables method. mcsl_clsExcelWork.LoadListboxWithTables
End Sub

Private Sub Form_Unload(Cancel As Integer)
Set mcls_clsExcelWork = Nothing
End Sub

Private Sub lstTables_DblClick()
Mcls_clsExcelWork.CreateWorksheet
End Sub


  增加標(biāo)準(zhǔn)的模塊到項(xiàng)目中,并將下列代碼加入到該模塊中:

Sub Main()
End Sub

關(guān)閉該模塊。

  如果你從未創(chuàng)建過(guò)類(lèi)模塊,那么你就要認(rèn)真對(duì)待,clsExcelWork是一個(gè)簡(jiǎn)單的類(lèi),工作一點(diǎn)兒也不困難。增加一個(gè)新的模塊到項(xiàng)目中,并將之命名為clsExcelWork,同時(shí)在聲明段中加入該類(lèi)(列表2)。

  列表2:clsExcelWork-增加新的類(lèi)模塊到項(xiàng)目中,然后在聲明段中加入新類(lèi)的代碼。

Option Explicit
Private xlsheetname As Excel.Worksheet

Private xlobj As Excel.Workbook
Private ExcelWasNotRunning As Boolean

Private Declare Function FindWindow Lib "user32" Alias _
    "FindWindowA" (ByVal lpClassName As String, ByVal _
     lpWindowName As Long) As Long

Private Declare Function SendMessage Lib "user32" Alias _
    "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, _
     ByVal wParam As Long, ByVal lParam As Long) As Long
創(chuàng)建下述方法:

Public Sub RunDLL()
注釋?zhuān)篶alled from the ActiveX container .
注釋?zhuān)簍his is the only public method .
frmMain.Show
End Sub

Friend Sub LoadListboxWithTables()
注釋?zhuān)篖oads the listbox on the form with the name of 注釋?zhuān)篺ive tables from the Northwind database.
With frmMain.lstTables
.AddItem "Categories"
.AddItem "Customers"
.AddItem "Employees"
.AddItem "Products"
.AddItem "Suppliers"
End With
End Sub

Private Sub GetExcel()
Dim ws

Set xlobj = GetObject(App.Path & "\DLLTest.xls")
xlobj.Windows("DLLTest.xls").Visible = True

If Err.Number <> 0 Then
ExcelWasNotRunning = True
End If
注釋?zhuān)篶lear Err object in case error occurred.
Err.Clear

注釋?zhuān)篊heck for Microsoft Excel . If Microsoft Excel is running ,
注釋?zhuān)篹nter it into the running Object table.

DetectExcel

注釋?zhuān)篊lear the old worksheets in the workbook .
xlobj.Application.DisplayAlerts = False

For Each ws In xlobj.Worksheets
If ws.Name <> "Sheet1" Then
ws.Delete
End If
Next

xlobj.Application.DisplayAlerts = True
End Sub

Private Sub DetectExcel()
Const WM_USER = 1024
Dim hwnd As Long
注釋?zhuān)篒f Excel is running , this API call return its handle .
hwnd = FindWindow("XLMAIN", 0)
注釋?zhuān)? means Excel isn’t running .
If hwnd = 0 Then
Exit Sub
Else 注釋?zhuān)篍xcel is running so use the SendMessage API function to
注釋?zhuān)篹nter it in the Running Object Table .
SendMessge hwnd, WM_USER + 18, 0, 0
End If
End Sub

Friend Sub CreateWorksheet()
Dim strJetConnString As String
Dim strJetSQL As String
Dim strJetDB As String
注釋?zhuān)篜repare Excel worksheet for the Querytable .
GetExcel
xlobj.Worksheets.Add
xlsheetname = xlobj.ActiveSheet.Name
xlobj.Windows("DLLTest.xls").Activate
注釋?zhuān)篗odify strJetDB to point to your installation of Northwind.mdb.
strJetDB = "c:\Program Files\Microsoft Office\Office\Samples\Northwind.mdb"

注釋?zhuān)篊reate a connection string.
strJetConnString = "ODBC;" & "DBQ=" & strJetDB & ";" & _
"Driver={Microsoft Access Driver (*.mdb)};"

注釋?zhuān)篊reate the SQL string
strJetSQL = "SELECT * FROM " & frmMain.lstTables.Text
注釋?zhuān)篊reate the QueryTable and populate the worksheet .
With xlobj.Worksheets(xlsheetname).QueryTables.Add(Connection:=strJetConnString, _
Destination:=xlobj.Worksheets(xlsheetname) _
.Range("A1"), Sql:=strJetSQL)
.Refresh (False)
End With
End Sub
 設(shè)計(jì)工作簿

  在你能夠測(cè)試這些代碼之前,你必須創(chuàng)建Excel工作簿,為了達(dá)到這個(gè)目的,打開(kāi)Excel,并且將缺省的book1存儲(chǔ)到自己的路徑\DLLTest.xsl下,該路徑是你以上創(chuàng)建的VB項(xiàng)目所在的路徑。

  在工作簿中,打開(kāi)VBA編輯器并在Excel菜單中選擇View>Toolbars>Visual Basic,在visual Basic工具條中點(diǎn)擊編輯按鈕。增加新模塊到編輯器中,并輸入下述代碼(列表3)。

  列表3:設(shè)計(jì)工作簿-增加新模塊和下述代碼。

Sub RunExcelDLL()
 注釋?zhuān)篊reates an instance of the new DLL and calls the main method .
 Dim x As New ExcelDLL.clsExcelWork
  x.RunDLL
 End Sub

Sub AddExcelDLLMenu()
注釋?zhuān)篈dds a new menu item so the DLL can be started.
On Error Resume Next
Set myMenubar = CommandBars.ActiveMenuBar

With myMenubar
With .Controls("Northwind DLL")
.Delete
End With
End With

Set newMenu = myMenubar.Controls.Add _
(Type := msoControlPopup, Temporary :=True)
newMenu.Caption = "Northwind DLL"
Set ctr11 = newMenu.Controls.Add(Type := msoControlButton, _
Id:=1)
With ctrl1
.Caption = "Run Northwind DLL"
.Style = msoButtonCaption
.OnAction = "RunExcelDLL"
End With
End sub

雙擊Microsoft Excel Objects中的ThisWorkbook,并輸入以下代碼:

Private Sub Workbook_BeforeClose(Cancel As Boolean)
On Error resume Next
Set x = Nothing
End sub

Private Sub Workbook_Open()
AddExcelDLLMenu
End Sub

  最后,保存Excel Workbook,此時(shí)不要試圖運(yùn)行該代碼,因?yàn)镈LL還沒(méi)有創(chuàng)建且沒(méi)有設(shè)置適當(dāng)?shù)囊谩?

  創(chuàng)建并引用ActiveX DLL

  為了創(chuàng)建ActiveX DLL,關(guān)閉Excel應(yīng)用程序,返回到Visual Basic項(xiàng)目,并執(zhí)行以下步驟:

  從菜單中點(diǎn)擊Project>Properties。

  在Project Properties對(duì)話框中,選擇ActiveX DLL作為項(xiàng)目的屬性,并點(diǎn)擊OK。在Project Name文本框中,輸入ExcelDLL。點(diǎn)擊Component標(biāo)簽并選中Project Compatibility。在底部的文本框中,輸入ExcelDLL.dll,以此確保新的DLL與以前的版本兼容。

  在Project Explorer中,點(diǎn)擊名為clsExcelWork的類(lèi),并設(shè)置實(shí)例屬性為5-MultiUse。

  點(diǎn)擊File菜單,并選擇Make ExcelDLL.dll,為了簡(jiǎn)單起見(jiàn),確認(rèn)你將DLL保存在項(xiàng)目和工作表所在的文件夾中。

  重新打開(kāi)Excel工作簿,并打開(kāi)VBA編輯器。

  點(diǎn)擊Tools>Reference。

  在對(duì)話框中,點(diǎn)擊Browse,并在ExcelDLL.dll創(chuàng)建時(shí)所在的文件夾中找到該文件,雙擊文件名。

  保存工作簿。

  關(guān)閉VBA編輯器和工作簿。

  當(dāng)你重新打開(kāi)工作簿,你可以點(diǎn)擊名為Northwind DLL的菜單,并選擇Run Northwind DLL,這樣將打開(kāi)DLL接口,選擇某個(gè)表格名,并點(diǎn)擊Open Table按鈕。如果所有的事情都處理得正確,DLL將移植你所選中的工作表中的數(shù)據(jù)。
  設(shè)計(jì)啟動(dòng)程序

  需要冷靜思考的是,用戶(hù)是否需要打開(kāi)特定的Excel工作表以訪問(wèn)該接口?如果你需要改變用戶(hù)的接口時(shí)將會(huì)發(fā)生什么?你是否需要重新編制安裝文件,是否需要與每一個(gè)用戶(hù)取得聯(lián)系,并使他們重新安裝相應(yīng)的應(yīng)用程序,把ActiveX DLL自動(dòng)地拷貝和注冊(cè)到用戶(hù)的機(jī)器上是否是一種好的方法?

  可執(zhí)行程序能夠檢查DLL而且在需要的時(shí)候更新并注冊(cè)DLL,接著繼續(xù)發(fā)送Execl并打開(kāi)你所創(chuàng)建的工作簿,幸運(yùn)的是,這是一種相當(dāng)直接的過(guò)程。開(kāi)始創(chuàng)建一個(gè)新個(gè)Visual basic項(xiàng)目并將之命名為RunExcelDLL,并刪除缺省的Form,再增加一個(gè)新模塊到basMain。增加下列代碼到模塊的聲明段:

Option Explicit

Private ExcelWasNotRunning As Boolean
Private Declare Function FindWindow Lib "user32" Alias _
"FindWindowA" (ByVal lpClassName As String , ByVal _
lpWindowName As Long ) As long Private Declare Function RegMyServerObject Lib _
"ExcelDll.dll" Alias "DllRegisterServer" () As Long
Private Declare Function ShellExecute Lib "shell32.dll" _
Alias "ShellExecuteA" (ByVal hwnd As Long , ByVal _
LpszOp As String , ByVal lpszFile As String , ByVal _
LpszParams As String , ByVal lpszFile As String , ByVal _
FsShowCmd As Long ) As Long

增加列表4的代碼到模塊中。

列表4:編制啟動(dòng)程序--在模塊中添加下列代碼。

Private Function RegisterDLL() As Boolean
On Error GoTo Err_DLL_Not_Registered
Dim RegMyDLLAttempted As Boolean

‘Attempt to register the DLL.
RegMyServerObject
RegisterDLL = True
Exit Function

Err_DLL_Not_Registered:
‘Check to see if error 429 occurs .
If err.Number = 429 Then

‘RegMyDLLAttempted is used to determine whether an
‘a(chǎn)ttempt to register the ActiveX DLL has already been
‘a(chǎn)ttempted. This helps to avoid getting stuck in a loop if
‘the ActiveX DLL cannot be registered for some reason .

RegMyDLLAttempeted = True
MsgBox " The new version of ExcelDll could not be _
Registered on your system! This application will now _
terminate. ", vbCritical, "Fatal Error"
Else
MsgBox "The new version of ExcelDLL could not be _
Registered on your system. This may occur if the DLL _
is loaded into memory. This application will now _
terminate . It is recommended that you restart your _
computer and retry this operation.", vbCritical, _ "Fatal Error".
End If

RegisterDLL = False
End Function

Sub Main()
Dim x
If UpdateDLL = True Then
DoShellExecute (App.Path & "\DLLTest.xls")
‘ frmODBCLogon.Show vbModal
Else
MsgBox "The application could not be started !", _
VbCritical , "Error"
End If
End
End Sub

Sub DoShellExecute(strAppPAth As String)
On Error GoTO CodeError
Dim res
Dim obj As Object
res = ShellExecute(0, "Open", strAppPath, _
VbNullString, CurDir$, 1)
If res<32 Then
MsgBox "Unable to open DllTest application"
End If

CodeExit
Exit Sub
CodeError:
Megbox "The following error occurred in the procedure " & _
StrCodeName & Chr(13) err.Number & " " & _
Err.Description, vbOKOnly, "Error Occurred"
GoTo CodeExit
End Sub

Function UpdateDLL() As Boolean
On Error GoTO err
Dim regfile
If CDate(FileDateTime(App.Path & "\Excel.dll")) <_
CDate(FileDateTime("C:\Temp\ExcelDLL.dll")) Then
If DetectExcel = True Then
MsgBox "Your version of ExcelDll needs to be updated, _
but Microsoft Excel is running. Please close Excel and _
restart this application so all files can be _
Replaced", vbOK, "Close Excel"
End
End If
If MsgBox("your version of ExcelDll is out of date, _
If you click on OK it will be replaced with the newest _
Version. Otherwise the application will terminate", _
VbOKCancel, "Replace Version?") = vbCancel Then
End
End If

If Dir(App.Path & "\ExcelDll.dll") > "" _
Then Kill App.Path & "\ExcelDll.dll"

FileCopy "c:\Temp\ExcelDll.dll", _
App.Path & "\ExcelDll.dll "

If RegisterDLL = True Then
UpdateDLL = True
Exit Function
Else
UpdateDLL = False
Exit Function
End If

Else
UpdateDLL = True
End If
Exit Function

err:
MegBox "The error " err.Number & "" & _
err.Description & "occurred"
UpdateDLL =False
End Function

Private Function DetectExcel() As Boolean
‘ Procedure detects a running Excel and registers it.
Const WM_USER = 1024
Dim hwnd As Long
注釋?zhuān)篒f Excel is running, this API call returns its handle.
hwnd = FindWindow("XLMAIN", 0)

If hwnd = 0 Then ‘0 means Excel not running.
DetectExcel = False
Else
DetectExcel = True
End If
End Function

相關(guān)頻道: eNews

您對(duì)本文或本站有任何意見(jiàn),請(qǐng)?jiān)谙路教峤?,謝謝!

投稿信箱:tougao@enet16.com