jacky1936

jacky1936

首页 CNDEV 网志 联络 (RSS 2.0) (Atom) 登录
  随笔 17 :: 收藏 6 :: 评论 4 :: 寻迹: 0

随笔归档

图库

2006-01-04 #

MSHTML 是微软公司的一个COM组件,该组件封装了HTML语言中的所有元素及其属性,通过其提供的标准接口,可以访问指定网页的所有元素.MSHTML对象模型是由一些对象和集合组成的.处于根部的是HTML,描述了打开页面的1个窗口,包括一系列集合和对象。如Frames集合,History, Location,Navigator,Document,Vi—sum,Event对象等.其中描述呈现在客户窗口实际网页的是Document对象。由一系列的属性、方法、对象和集合组成.其中All集合中包含网页中所有标记(Tag)元素,其主要的方法和属性有:
(1)Length(长度):即标记出现的个数,可以把标记的集合理解为从0开始的一维数组,其次序按照标记在网页位置排列;
(2)Tags(标记):用于过滤出给定标记的集合,如Doc.Al1.Tags(P)得到所有分段标记P;
(3)Item(项目):用于选择集合中的某1个元素,如object.item(0)得到集合的第1个元素,而object.item(i)得到第i+1个元素.
此外,IHTMLElement也是个常用的集合对象,代表网页中指定标记的集合,通过这个集合对象,可以得到网页上特定标记的内容.IHTMLElement有4个主要属性:
(1)InnerText:开始标记和结束标记之间的文本;
(2)InnerHTML:开始标记和结束标记之间的文本和HTML;
(3)OuterText:对象的文本;
(4)OuterHTML:对象的文本和HTML.

procedure TForm1.Button1Click(Sender: TObject);
var
Doc:IHTMLDocument2;
input:OleVariant;
userinputelement,pwdinputelement:ihtmlinputelement;
begin
doc:=webbrowser1.document as ihtmldocument2;
userinputelement:=(doc.all.item('user'(也就是网页中用户名控件的名字),0) as ihtmlinputelement);
userinputelement.value:=edit1.text;(也就是你要向网页输入的东西)
pwdinputelement:=(doc.all.item('password',0) as ihtmlinputelement);
pwdinputelement.value:=edit2.text;
input:=doc.all.item('submit',0);
input.click;
end;  

当提交数据按钮没有NAME属性时,采用如下方法:

procedure TForm1.Button1Click(Sender: TObject);
var
Doc:IHTMLDocument2;
form:ithmlformelement;
userinputelement,pwdinputelement:ihtmlinputelement;

begin
doc:=webbrowser1.document as ihtmldocument2;
userinputelement:=(doc.all.item('user'(也就是网页中用户名控件的名字),0) as ihtmlinputelement);
userinputelement.value:=edit1.text;(也就是你要向网页输入的东西)
pwdinputelement:=(doc.all.item('password',0) as ihtmlinputelement);
pwdinputelement:=edit2.text;
form:=(doc.all.item('login_form',0) as ihtmlformelement):
form.submit;
end;  

发表于 @ 23:38 | 评论与反馈 (1)

偶然的机会需要使用TWebBrowser,在开发过程中涉及到一些比较不肤浅的东西,于是免不了搜资料,翻CSDN的帖子,终于把要做的东西作了出来,同时对于TWebBrowser也有了初步的了解。同时看到很多CSDN上的不少朋友也在TWebBrowser上存在很多疑问,于是把自己这段时间所得的拿出来与大家分享。还是那句话,本人水平很洼,说的不对的话敬请指出,不要客气,否则不但我自己学错了东西,也让看这篇文章的人误入歧途。废话少说正文开始。

首先我们要认识到TWebBrowser其实是Delphi对Internet Explorer Browser的封装,也就是说它是一个ActiveX控件,看过TWebBrowser代码的朋友会发现这个空间的所有方法的实现部分都调用了DefaultInterface的方法,而TWebBrowser的这个属性是一个IWebBrowser2接口类型的对象,这个接口就是IE的接口。我们在使用TWebBrowser代替IE浏览器的目的大部分是为了能够让程序处理页面,实现自动对WebApplication的请求,所以我们首先想得到的就是TWebBrowser所浏览的内容。TWebBrowser的Documnet属性正是这一内容,Document其实是一个IHTMLDocument2,但是它被声明为IDispatch接口类型,我们需要把它转化为IHTMLDocument2类型然后是用我们需要的各种方法。在这里需要注意IHTMLDocument2是在MSHTML单元定义的,需要我们手动将这一单元加入到uses部分。具体代码如下:

var D : IHTMLDocument2;
begin 
  D := WebBrowser1.Document as IHTMLDocument2;
end;

接下来我们来看看一个网页中包含什么,也就是我们希望通过TWebBrowser来处理的内容有哪些。网页中的元素主要有普通文本内容,超级连接以及动态的元素(Form中的元素),当然还有其它元素,但是我们在一般的处理过程中一般会用到这些,因此我在这里以这些元素为例首先我要介绍的是Form和包含在Form中的元素的使用。

在IHTMLDocument接口中有一个Forms的属性,这个属性是IHTMLElementCollection接口类型,其实这个Forms属性是TWebBrowser显示的页面中的所有Form元素。也就是说一个页面中的所有Form都包含在Forms这个集合中。我们可以以使用IHTMLDocument.Forms.item(name: OleVariant; index: OleVariant)得到我们需要操作的Form,当然我们在这里得到的只是一个IDispatch接口,我们需要再把这个接口转换成IHTMLFormElement来使用Form的方法和属性。示例如下(该例子为yahoo的免费信箱登陆界面http://mail.yahoo.com.cn):

var Form :  IHTMLFormElement  ;
    D:IHTMLDocument2  ;

begin
  with WebBrowser1 do begin
     D := Document as IHTMLDocument2;
     Form := D.Forms.item('login_form',0) as IHTMLFormElement;
     (form.item('login',0) as IHTMLElement).setAttribute('value',edit1.Text,0);
     (form.item('passwd',0) as IHTMLElement).setAttribute('value',edit2.Text,0);
     //form.submit; // this line work too
     (form.item('.save',0) as IHTMLElement).click;
  end;
end;

从上面的例子我们可以看到我们可以通过两种方法提交一个Form,这两种方法在一般情况下没有什么区别,但是当页面中编写了一些js用来实现页面提交的控制时,前者会忽略掉这些js,所以后面的方法是我所推荐的。

在这个时候我遇到了一个问题,就是在我要处理的页面中有两个Form,而且这样两个Form都没有名字,也就是说Form := D.Forms.item('login_form',0) as IHTMLFormElement;这一句中item的第一个参数的我们无法从网页中得到,同时在设置这个参数时我发现了一个问题,就是说如果在页面中有两个Form元素的话,第一个Form元素可以通过item(varEmpty,0)得到,第二个Form元素可以通过item(verNull,0)得到,而item的第二个参数完全不起作用,这个问题可能是由于我对该函数的错误使用造成的,希望有人可以给出这一问题的解决方案(我在自己翻看帖子是找到了答案,的确是我对该函数的参数的错误使用造成的,第一个参数应该是我们要使用的对象的索引值。)。我的想法是DHTML在没有明确得到一个元素的名称时会自动生成一个唯一的元素名称分配给该元素,但是如何得到这个唯一的元素名称呢?这个只是我的一个设想,我们会看到,当我们处理链接的时候我们还要遇到这个问题。示例如下(

这是我自己做的一个jsp程序):
var   form : IHTMLFormElement  ;
     d:IHTMLDocument2  ;
begin
  with WebBrowser1 do begin
     d := document as IHTMLDocument2;
     form := d.forms.item(varNull,01) as IHTMLFormElement;
     (form.item('firstName',0) as IHTMLElement).setAttribute('value',edit1.Text,0);
     (form.item('lastName',0) as IHTMLElement).setAttribute('value',edit1.Text,0);
     form.submit;
  end;
end;

以上是网页中Form的基本处理,接下来我介绍一下网页中对于链接的控制,我们一般是希望能够实现程序自动点击网页中的连接。在这里正如前面提到的,我只能得到前两个没有名称的连接。示例如下:

var  Links : IHTMLElementCollection;
     D:IHTMLDocument2  ;
     Element : IHTMLElement;
begin
  with WebBrowser1 do begin
    D := Document as IHTMLDocument2;
    Links := D.links;
    Element := (Links.Item(varempty,0) as IHTMLElement);
    ShowMessage(Element.getAttribute('href',0));
    Element := (Links.Item(varNull,0) as IHTMLElement);
    ShowMessage(Element.getAttribute('href',0));
  end;
end;

我们可以通过调用以上代码中的Element.Click事件来模拟点击。不行了,写不下去了,还有一个常见的问题就是怎么使自己写的Browser在打开一个新窗口时在制定窗口打开。这个要在TWebBrowser的NewWindows2中改变 ppDisp来实现。

就是这么多,希望大家能够从中学到点什么,更希望有人能够解答我上面的疑问。

版权所有:idilent 网站转载请注明作者 其他转载方式请与作者联系(idilent@yahoo.

发表于 @ 23:37 | 评论与反馈 (2)

2006-01-02 #

壹、把用户权限体系用数据库来实现(包括对应部门)

贰、数据库的异常如何能用DELPHI截获并解释

叁、c/s系统网络加密的问题

发表于 @ 22:15 | 评论与反馈 (0)

2005-12-28 #

不过,天天能记点东西还是不错滴
发表于 @ 21:31 | 评论与反馈 (0)

如果这个日记本能备份到本地多好啊,要是能够存点文件就更好了,呵呵
发表于 @ 17:53 | 评论与反馈 (0)

2005-12-27 #

VFP的DBF文件访问竟然tmd要专门有驱动vfpoledb,靠,真麻烦
发表于 @ 12:45 | 评论与反馈 (0)

居然写的还很快,看来我是脱不开写这些东西了,呵呵,有把以前的东西再整理一次的冲动,哈哈
发表于 @ 00:24 | 评论与反馈 (0)

2005-12-26 #

今天很郁闷,今天很郁闷,今天很郁闷,今天很郁闷,今天很郁闷,今天很郁闷,今天很郁闷,今天很郁闷,今天很郁闷,今天很郁闷,今天很郁闷,今天很郁闷,今天很郁闷!
发表于 @ 13:13 | 评论与反馈 (0)

真的是个问题,今天别人的工作没有完成,本来如果是抓紧时间是可以完成的,但是由于大部分时间都没有作工作,所以本来以为自己剩下的时间能完成,结果碰到了意想不到的困难,但我觉得工作应该是放在第一位的,总是一天上上网,看电视,唉,连深入的了解技术的兴趣都没有,咋整?怎么才能引导好呢?
发表于 @ 00:21 | 评论与反馈 (0)

2005-12-25 #

“需要吃多少,就点多少!钱是你自己的,但资源是全社会的,世界上有很多人还缺少资源,你们不能够也没有理由浪费”,有的时候看到别人浪费真的不知道怎么说好
发表于 @ 20:28 | 评论与反馈 (0)

2005-12-24 #

发短信等手机通讯有三种方式:
1.移动、联通网关,一般是通过宽带网连接
2.通过在163、sohu、sina等网站注册手机,编写程序来发送短信
3.红外或串口与手机通信,分Text和PDU两种传送模式。其中,Nokia手机还可以分为需要数据套件、免数据套件(二进制)两种方式。

好像比较好用是GPRS MODEM

以下的链接
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2578107

发表于 @ 23:57 | 评论与反馈 (0)

最近收集一下资料,呵呵
发表于 @ 01:16 | 评论与反馈 (0)

2005-12-23 #

http://support.microsoft.com/kb/316934/EN-US/#XSLTH4202121122120121120120
需要注意的是用ADO.NET来改EXCEL单元格的值,要注意原来是字符串改成字符串,原来是数值改成数值都可以,但要是交错的修改就会出错的,我觉得是EXCEL在保存时把单元格的内容的类型也保存了,ADO.NET修改后,它再打开,它觉得上当了。
从Excel返回DataSet

问题:Excel某列为时间格式,但实际存储数据的时候可能写入的是字符串文本。用上述方法返回DataSet中无法读取此列文本数据。
解决方案:很简单,string strConn= "Provider=Microsoft.Jet.OleDb.4.0;" + "data source="+Path+ ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'";

"HDR=Yes;" indicates that the first row contains columnnames, not data
"IMEX=1;" tells the driver to always read "intermixed" data columns as text
下面是最专业的文章:
 

Article Translations

 

Other Support Options

Contact Microsoft
Phone Numbers, Support Options and Pricing, Online Help, and more.
Customer Service
For non-technical assistance with product purchases, subscriptions, online services, events, training courses, corporate sales, piracy issues, and more.
Newsgroups
Pose a question to other users. Discussion groups and Forums about specific Microsoft products, technologies, and services.

How To Use ADO.NET to Retrieve and Modify Records in an Excel Workbook With Visual Basic .NET

Article ID : 316934
Last Review : July 14, 2004
Revision : 7.1
This article was previously published under Q316934

SUMMARY

This article discusses how you can use ADO.NET to retrieve data from a Microsoft Excel workbook, modify data in an existing workbook, or add data to a new workbook. To access Excel workbooks with ADO.NET, you can use the Jet OLE DB provider; this article provides the information that you need so that you can use the Jet OLE DB provider when Excel is the target data source.

How to Use the Jet OLE DB Provider With Microsoft Excel Workbooks

The Microsoft Jet database engine can access data in other database file formats, such as Excel workbooks, through installable Indexed Sequential Access Method (ISAM) drivers. To open external formats supported by the Microsoft Jet 4.0 OLE DB Provider, specify the database type in the extended properties for the connection. The Jet OLE DB Provider supports the following database types for Microsoft Excel workbooks:
Excel 3.0
Excel 4.0
Excel 5.0
Excel 8.0
NOTE: Use the Excel 5.0 source database type for Microsoft Excel 5.0 and 7.0 (95) workbooks and use the Excel 8.0 source database type for Microsoft Excel 8.0 (97), 9.0 (2000) and 10.0 (2002) workbooks. The examples in this article use Excel workbooks in the Excel 2000 and Excel 2002 format.

Connection String

To access an Excel workbook by using the Jet OLE DB Provider, use a connection string that has the following syntax:
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Book1.xls;Extended Properties="Excel 8.0;HDR=YES;"
In the connection string, specify the full path and file name for the workbook in the Data Source parameter. The Extended Properties parameter may contain two properties: a property for the ISAM version and a property to indicate whether or not the table(s) include headers.

With Excel workbooks, the first row in a range is the header row (or field names) by default. If the first range does not contain headers, you can specify HDR=NO in the extended properties in your connection string. If you specify HDR=NO in the connection string, the Jet OLE DB provider automatically names the fields for you (F1 represents the first field, F2 represents the second field, and so on).

Data Types

Unlike a traditional database, there is no direct way to specify the data types for columns in Excel tables. Instead, the OLE DB provider scans eight rows in a column to guess the data type for the field. You can change the number of rows to scan by specifying a value between one (1) and sixteen (16) for the MAXSCANROWS setting in the extended properties of your connection string.

Table Naming Conventions

There are several ways you can reference a table (or range) in an Excel workbook:
Use the sheet name followed by a dollar sign (for example, [Sheet1$] or [My Worksheet$]). A workbook table that is referenced in this manner includes the whole used range of the worksheet.
Select * from [Sheet1$]
Use a range with a defined name (for example, [MyNamedRange]):
Select * from [MyNamedRange]
Use a range with a specific address (for example, [Sheet1$A1:B10]):
Select * from [Sheet1$A1:B10]
NOTE: The dollar sign following the worksheet name is an indication that the table exists. If you are creating a new table, as discussed in the Create New Workbooks and Tables section of this article, do not use the dollar sign.

How to Use Excel Workbooks as ADO.NET Data Sources

Retrieve Records

You can retrieve records from a database by using one of two approaches in ADO.NET: with a Dataset or with a DataReader.

A Dataset is a cache of records retrieved from a data source. The data in the Dataset is usually a much-reduced version of what is in the database. However, you can work with it in the same way that you work with the actual data and remain disconnected from the actual database. Besides data retrieval, you can also use a Dataset to perform update operations on the underlying database.

Alternatively, you can use a DataReader to retrieve a read-only, forward-only stream of data from a database. When you use the DataReader program, performance increases and system overhead is decreases because only one row at a time is ever in memory. If you have a large quantity of data to retrieve and you do not intend to make changes to the underlying database, a DataReader is a better choice than a Dataset.

Add and Update Records

With ADO.NET, you can insert and update records in a workbook in one of three ways:
Directly run a command to insert or update records one at a time. To do this, you can create an OLEDbCommand object on your connection and set its CommandText property to a valid command to insert records

INSERT INTO [Sheet1$] (F1, F2) values ('111', 'ABC')
or a command to update records

UPDATE [Sheet1$] SET F2 = 'XYZ' WHERE F1 = '111'
and then call the ExecuteNonQuery method.
Make changes to a DataSet that you have filled with a table/query from an Excel workbook and then call the Update method of the DataAdapter to resolve changes from the DataSet back to the workbook. However, to use the Update method for change resolution you must set parameterized commands for the DataAdapter's InsertCommand
INSERT INTO [Sheet1$] (F1, F2) values (?, ?)
and UpdateCommand:
UPDATE [Sheet1$] SET F2 = ? WHERE F1 = ?
Parameterized INSERT and UPDATE commands are required because the OleDbDataAdapter does not supply key/index information for Excel workbooks; without key/index fields, the CommandBuilder cannot automatically generate the commands for you.
Export data from another data source into an Excel workbook provided that the other data source can be used with the Jet OLE DB Provider. Data sources that you can use with the Jet OLE DB Provider in this manner include Text files, Microsoft Access databases, and, of course, other Excel workbooks. With a single INSERT INTO command, you can export data from another table/query into your workbook:
INSERT INTO [Sheet1$] IN 'C:\Book1.xls' 'Excel 8.0;' SELECT * FROM MyTable"
INSERT INTO requires that the target table (or worksheet) already exist; data is appended to the target table.

You may also use SELECT..INTO to export your table/query to a workbook:
SELECT * INTO [Excel 8.0;Database=C:\Book1.xls].[Sheet1] FROM [MyTable]
When you use SELECT..INTO, if the target table or workbook does not exist, it will be created for you. If the table already exists before the SELECT..INTO command is issued, you will receive an error.
The Sample Code section later in this article illustrates each of these approaches to add and update records in a workbook.

Delete Records

Although the Jet OLE DB Provider allows you to insert and update records in an Excel workbook, it does not allow DELETE operations. If you try to perform a DELETE operation on one or more records, you receive the following error message:
Deleting data in a linked table is not supported by this ISAM.
This limitation is inherent in the treatment of Excel workbooks as databases.

Create Workbooks and Tables

To create a table in an Excel workbook, run the CREATE TABLE command:
CREATE TABLE Sheet1 (F1 char(255), F2 char(255))
When you run this command, a new worksheet is created with the name of the table you specify in the command. If the workbook for the connection does not exist, it too will be created.

The Sample Code section illustrates how you can use the CREATE TABLE command to create a new workbook and table.

Step-by-Step

Sample Code

1. Start a new Visual Basic .NET Windows Application project.

Form1 is created by default.
2. Add six RadioButton controls and a Button control to Form1.
3. Select all of the RadioButton controls and set the Size property to 200,24.
4. On the View menu, click Code.
5. Add the following line to the very beginning of the code module:
Imports System.Data.OleDb
6. Insert the following code into the Form class:
Private m_sConn1 As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
               "Data Source=C:\ExcelData1.xls;" & _
               "Extended Properties=""Excel 8.0;HDR=YES"""

Private m_sConn2 As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
               "Data Source=C:\ExcelData2.xls;" & _
               "Extended Properties=""Excel 8.0;HDR=YES"""

Private m_sNorthwind = _
      "C:\Program Files\Microsoft Office\Office10\Samples\Northwind.mdb"

Private m_sAction As String

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      RadioButton1.Text = "Create_Workbook"
      RadioButton2.Text = "Retrieve_Records"
      RadioButton3.Text = "Add_Records"
      RadioButton4.Text = "Update_Records"
      RadioButton5.Text = "Update_Individual_Cells"
      RadioButton6.Text = "Use_External_Source"
      Button1.Text = "Go!"
End Sub

Private Sub RadioButtons_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
      Handles RadioButton1.Click, RadioButton2.Click, RadioButton3.Click, _
      RadioButton4.Click, RadioButton5.Click, RadioButton6.Click
      m_sAction = sender.Text'Store the text for the selected radio button
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
      Try
         ' Call the associated routine to add/update/modify the workbook.
         Select Case m_sAction
            Case "Create_Workbook" : Create_Workbook()
            Case "Retrieve_Records" : Retrieve_Records()
            Case "Add_Records" : Add_Records()
            Case "Update_Records" : Update_Records()
            Case "Update_Individual_Cells" : Update_Individual_Cells()
            Case "Use_External_Source" : Use_External_Source()
         End Select

      Catch ex As OleDbException
         Dim er As OleDbError
         For Each er In ex.Errors
            MsgBox(er.Message)
         Next
      Catch ex2 As System.InvalidOperationException
         MsgBox(ex2.Message)
      End Try


End Sub

Public Sub Create_Workbook()

      ' If the workbooks already exist, prompt to delete.
      Dim answer As MsgBoxResult
      If Dir("C:\ExcelData1.xls") <> "" Or Dir("C:\ExcelData2.xls") <> "" Then
          answer = MsgBox("Delete existing workbooks (C:\ExcelData1.xls and " & _
                   "C:\ExcelData2.xls)?", MsgBoxStyle.YesNo)
          If answer = MsgBoxResult.Yes Then
              If Dir("C:\ExcelData1.xls") <> "" Then Kill("C:\ExcelData1.xls")
              If Dir("C:\ExcelData2.xls") <> "" Then Kill("C:\ExcelData2.xls")
          Else
              Exit Sub
          End If
      End If

'==========================================================================
      ' Create a workbook with a table named EmployeeData. The table has 3
      ' fields: ID (char 255), Name (char 255) and Birthdate (date).
'==========================================================================
      Dim conn As New OleDbConnection()
      conn.ConnectionString = m_sConn1
      conn.Open()
      Dim cmd1 As New OleDbCommand()
      cmd1.Connection = conn
      cmd1.CommandText = "CREATE TABLE EmployeeData (Id char(255), Name char(255), BirthDate date)"
      cmd1.ExecuteNonQuery()
      cmd1.CommandText = "INSERT INTO EmployeeData (Id, Name, BirthDate) values ('AAA', 'Andrew', '12/4/1955')"
      cmd1.ExecuteNonQuery()
      conn.Close()

'==========================================================================
      ' Create a workbook with a table named InventoryData. The table has 3
      ' fields: Product (char 255), Qty (float) and Price (currency).
'==========================================================================

      conn.ConnectionString = m_sConn2
      conn.Open()
      Dim cmd2 As New OleDbCommand()
      cmd2.Connection = conn
      cmd2.CommandText = "CREATE TABLE InventoryData (Product char(255), Qty float, Price currency)"
      cmd2.ExecuteNonQuery()
      cmd2.CommandText = "INSERT INTO InventoryData (Product, Qty, Price) values ('Cola', 200, 1.35)"
      cmd2.ExecuteNonQuery()
      cmd2.CommandText = "INSERT INTO InventoryData (Product, Qty, Price) values ('Chips', 550, 0.89)"
      cmd2.ExecuteNonQuery()
      conn.Close()

      ' NOTE: You can ALTER and DROP tables in a similar fashion.

End Sub

Public Sub Retrieve_Records()

      '==========================================================
      'Use a DataReader to read data from the EmployeeData table.
      '==========================================================

      Dim conn1 As New System.Data.OleDb.OleDbConnection(m_sConn1)
      conn1.Open()
      Dim cmd1 As New System.Data.OleDb.OleDbCommand("Select * From [EmployeeData$]", conn1)
      Dim rdr As OleDbDataReader = cmd1.ExecuteReader

      Debug.WriteLine(vbCrLf & "EmployeeData:" & vbCrLf & "=============")
      Do While rdr.Read()
         Debug.WriteLine(System.String.Format("{0,-10}{1, -15}{2}", _
            rdr.GetString(0), rdr.GetString(1), _
            rdr.GetDateTime(2).ToString("d")))
      Loop
      rdr.Close()
      conn1.Close()

      '========================================================
      'Use a DataSet to read data from the InventoryData table.
      '========================================================
      Dim conn2 As New OleDbConnection(m_sConn2)
      Dim da As New OleDbDataAdapter("Select * From [InventoryData$]", conn2)
      Dim ds As DataSet = New DataSet()
      da.Fill(ds)
      Debug.WriteLine(vbCrLf & "InventoryData:" & vbCrLf & "==============")
      Dim dr As DataRow
      For Each dr In ds.Tables(0).Rows'Show results in output window
         Debug.WriteLine(System.String.Format("{0,-15}{1, -6}{2}", _
            dr("Product"), dr("Qty"), dr("Price")))
      Next
      conn2.Close()

End Sub

Public Sub Add_Records()

'==========================================================================
      ' Run an INSERT INTO command to add new records to the workbook.
'==========================================================================
      Dim conn1 As New System.Data.OleDb.OleDbConnection(m_sConn1)
      conn1.Open()
      Dim cmd As New System.Data.OleDb.OleDbCommand()
      cmd.Connection = conn1
      cmd.CommandText = "INSERT INTO [EmployeeData$] (ID, Name, BirthDate) values ('CCC', 'Charlie', '10/14/48')"
      cmd.ExecuteNonQuery()
      cmd.CommandText = "INSERT INTO [EmployeeData$] (ID, Name, BirthDate) values ('DDD', 'Deloris', '7/19/98')"
      cmd.ExecuteNonQuery()
      conn1.Close()

      '====================================================================
      'Use the InsertCommand object to add new records to the InventoryData
      'table.
      '====================================================================
      Dim conn2 As New OleDbConnection(m_sConn2)
      Dim da As New OleDbDataAdapter("Select * From [InventoryData$]", conn2)
      Dim ds As DataSet = New DataSet()
      da.Fill(ds, "MyExcelTable")

      ' Generate the InsertCommand and add the parameters for the command.
      da.InsertCommand = New OleDbCommand( _
         "INSERT INTO [InventoryData$] (Product, Qty, Price) VALUES (?, ?, ?)", conn2)
      da.InsertCommand.Parameters.Add("@Product", OleDbType.VarChar, 255, "Product")
      da.InsertCommand.Parameters.Add("@Qty", OleDbType.Double).SourceColumn = "Qty"
      da.InsertCommand.Parameters.Add("@Price", OleDbType.Currency).SourceColumn = "Price"

      ' Add two new records to the dataset.
      Dim dr As DataRow
      dr = ds.Tables(0).NewRow
      dr("Product") = "Bread" : dr("Qty") = 390 : dr("Price") = 1.89 : ds.Tables(0).Rows.Add(dr)
      dr = ds.Tables(0).NewRow
      dr("Product") = "Milk" : dr("Qty") = 99 : dr("Price") = 2.59 : ds.Tables(0).Rows.Add(dr)

      ' Apply the dataset changes to the actual data source (the workbook).
      da.Update(ds, "MyExcelTable")
      conn2.Close()

End Sub

Public Sub Update_Records()

'==========================================================================
      ' Run an UPDATE command to change a record in the EmployeeData
      ' table.
'==========================================================================
      Dim conn1 As New System.Data.OleDb.OleDbConnection(m_sConn1)
      conn1.Open()
      Dim cmd As New System.Data.OleDb.OleDbCommand()
      cmd.Connection = conn1
      cmd.CommandText = "UPDATE [EmployeeData$] " & _
                    "SET NAME = 'Aaron', BirthDate = '5/4/1975' WHERE ID = 'AAA'"
      cmd.ExecuteNonQuery()
      conn1.Close()

      '====================================================================
      ' Use the UpdateCommand object to modify records in the InventoryData
      ' table.
      '====================================================================
      Dim conn2 As New OleDbConnection(m_sConn2)
      Dim da As New OleDbDataAdapter("Select * From [InventoryData$]", conn2)
      Dim ds As DataSet = New DataSet()
      da.Fill(ds, "MyInventoryTable")

      ' Generate the UpdateCommand and add the parameters for the command.
      da.UpdateCommand = New OleDbCommand( _
         "UPDATE [InventoryData$] SET Qty = ?, Price=? WHERE Product = ?", conn2)
      da.UpdateCommand.Parameters.Add("@Qty", OleDbType.Numeric).SourceColumn = "Qty"
      da.UpdateCommand.Parameters.Add("@Price", OleDbType.Currency).SourceColumn = "Price"
      da.UpdateCommand.Parameters.Add("@Product", OleDbType.VarChar, 255, "Product")

      ' Update the first two records.
      ds.Tables(0).Rows(0)("Qty") = 1000
      ds.Tables(0).Rows(0)("Price") = 10.1
      ds.Tables(0).Rows(1)("Qty") = 2000
      ds.Tables(0).Rows(1)("Price") = 20.2

      ' Apply the dataset changes to the actual data source (the workbook).
      da.Update(ds, "MyInventoryTable")
      conn2.Close()

End Sub

Public Sub Update_Individual_Cells()

'==========================================================================
      ' Update individual cells on the EmployeeData worksheet;
      ' specifically, cells F3, G3, and I4 are modified.
'==========================================================================

      ' NOTE: The connection string indicates that the table does *NOT*
      ' have a header row.
      Dim conn As New System.Data.OleDb.OleDbConnection(m_sConn1.Replace("HDR=YES", "HDR=NO"))
      conn.Open()
      Dim cmd As New System.Data.OleDb.OleDbCommand()
      cmd.Connection = conn
      cmd.CommandText = "UPDATE [EmployeeData$F3:G3] SET F1 = 'Cell F3', F2 = 'Cell G3'"
      cmd.ExecuteNonQuery()
      cmd.CommandText = "UPDATE [EmployeeData$I4:I4] SET F1 = 'Cell I4'"
      cmd.ExecuteNonQuery()
      conn.Close()

End Sub

Public Sub Use_External_Source()

      ' Open a connection to the sample Northwind Access database.
      Dim conn As New System.Data.OleDb.OleDbConnection( _
            "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & m_sNorthwind & ";")
      conn.Open()
      Dim cmd As New System.Data.OleDb.OleDbCommand()
      cmd.Connection = conn

'=======================================================================
      ' Run an INSERT..INTO command on the Northwind database to append
      ' the records from a table/query to an existing table in the Excel
      ' workbook.
'=======================================================================
      cmd.CommandText = "INSERT INTO [EmployeeData$] IN 'C:\ExcelData1.xls' 'Excel 8.0;'" & _
         "SELECT EmployeeID AS ID, FirstName AS Name, BirthDate FROM Employees"
      cmd.ExecuteNonQuery()

'==========================================================================
      ' Run a SELECT..INTO command on the Northwind database to insert
      ' all the records from a table/query into a new sheet in the Excel
      ' workbook.
'==========================================================================
      cmd.CommandText = "SELECT * INTO [Excel 8.0;Database=C:\ExcelData2.xls].[ProductSales]" & _
                      "FROM [Product Sales for 1997]"
      cmd.ExecuteNonQuery()

      conn.Close()

End Sub
7. Modify the path to the sample Access database, Northwind, for the m_sNorthwind member in the code, if necessary.

Try It Out

1. On the View menu, point to Other Windows, and then click Output to display the Output window.
2. Press F5 to build and run the program.
3. Click Create_Workbook and then click Go. The Create_Workbook procedure runs CREATE TABLE commands to create two new workbooks: C:\ExcelData1.xls and C:\ExcelData2.xls. ExcelData1.xls contains one sheet (table) named EmployeeData and ExcelData2.xls contains one sheet (table) named InventoryData. The tables are filled with records.

NOTE: At each remaining step in this test, open the workbooks in Excel to examine the results. Or, click Retrieve_Records to view the contents of the table(s) in the Output Window of Visual Studio .NET.
4. Click Retrieve_Records and then click Go. The Retrieve_Records procedure extracts the records from the tables and displays them in the Output window, similar to this:
EmployeeData:
=============
AAA       Andrew         12/4/1955

InventoryData:
==============
Cola           200   1.35
Chips          550   0.89
5. Click Add_Records and then click Go. The Add_Records routine adds two records to each table:
EmployeeData:
=============
AAA       Andrew         12/4/1955
CCC       Charlie        10/14/1948
DDD       Deloris        7/19/1998

InventoryData:
==============
Cola           200   1.35
Chips          550   0.89
Bread          390   1.89
Milk           99    2.59
6. Click Update_Records and then click Go. The Update_Records routine updates two records in each workbook:
EmployeeData:
=============
AAA       Aaron          5/4/1975
CCC       Charlie        10/14/1948
DDD       Deloris        7/19/1998

InventoryData:
==============
Cola           1000  10.1
Chips          2000  20.2
Bread          390   1.89
Milk           99    2.59
7. Click Update_Individual_Cells and then click Go. The Update_Individual_Cells routine modifies specific cells on the EmployeeData worksheet in ExcelData1.xls; specifically, cells F3, G3, and I4 are updated.
8. Click Use_External_Source and then click Go. When you use an INSERT..INTO command, the Use_External_Source routine appends records from the Northwind table 'Employees' to the EmployeeData worksheet in ExcelData1.xls. And, Use_External_Source uses a SELECT..INTO command to create a new table (or sheet) in ExcelData2.xls that contains all of the records from the Northwind table 'Products'.

NOTE: If you click Use_External_Source more than one time, the Employees list will be appended multiple times because the primary key is not recognized or enforced.

Cell Formatting

If you are using ADO.NET to add or update records in an existing workbook, you can apply cell formatting to the workbook that will be used with the new or updated records. When you update an existing record (or row) in a workbook, the cell formatting is retained. And when you insert a new record (or row) in a workbook, the new record inherits formatting from the row above it.

The following procedure shows how you can use formatting in a workbook with the sample code:
1. Press F5 to build and run the sample.
2. On Form1, click Create_Workbook and then click Go.
3. Start Microsoft Excel and open C:\ExcelData1.xls.
4. Apply a bold font style to cell A2.
5. Apply an italic, underline style to cell B2 and align center.
6. Apply a long date format to cell C2.
7. Save and close C:\ExcelData1.xls.
8. On Form1, click Add_Records and then click Go.
9. Open C:\ExcelData1.xls in Excel and notice that the two new rows have inherited the formatting from the first row.

Limitations

The following are some limitations of the Jet OLE DB Provider in regard to Excel data sources:
You cannot insert formulas in cells using ADO.NET.
The Jet OLE DB Provider is unable to provide key/index information for tables in an Excel workbook. For this reason, you cannot use the CommandBuilder to automatically generate updates and insertions for records in an Excel workbook.

REFERENCES

For additional information, click the following article numbers to view the articles in the Microsoft Knowledge Base:
316756 (http://support.microsoft.com/kb/316756/) PRB: Error Occurs When You Use ADO.NET OLEDbDataAdapter to Modify Excel Workbook
257819 (http://support.microsoft.com/kb/257819/EN-US/) How To Use ADO with Excel Data from Visual Basic or VBA
306022 (http://support.microsoft.com/kb/306022/) How To Transfer Data to an Excel Workbook by Using Visual Basic .NET
306023 (http://support.microsoft.com/kb/306023/) How To Transfer Data to an Excel Workbook Using Visual C# .NET
311731 (http://support.microsoft.com/kb/311731/) How To Query and Display Excel Data by Using ASP.NET, ADO.NET and Visual Basic .NET
306572 (http://support.microsoft.com/kb/306572/) How To Query and Display Excel Data by Using ASP.NET, ADO.NET, and Visual C# .NET
278973 (http://support.microsoft.com/kb/278973/) SAMPLE: ExcelADO Demonstrates How to Use ADO to Read and Write Data in Excel Workbooks


APPLIES TO
Microsoft .NET Framework 1.1 Service Pack 1
Microsoft Office Excel 2003
Microsoft Excel 2002 Standard Edition
Microsoft Excel 2000 Standard Edition
Microsoft Visual Basic .NET 2002 Standard Edition
Keywords: 
kbhowtomaster KB316934
Did this content help you?
Yes
No
Maybe
Please select one option based on your first choice:
I'm very satisfied
I think it will help, but I haven't tried it yet
It is helpful, but I need more information
It is helpful, but hard to understand
Seemed relevant in search results, but didn't help me
The information is wrong
The page contains one or more broken links
Suggest new content or let us know how we can improve this content (optional):

©2005 Microsoft Corporation. 版权所有.  保留所有权利 |商标 |隐私权声明
发表于 @ 22:22 | 评论与反馈 (0)

2005-01-28 #

风焱在《“18般武艺”?》中说到他碰上的被多种语言纠缠的问题。我在回复里说:
 很多语言只要能看懂几分就行了,没必要每一种都精通
但是如果只会很少的一两种语言也是不行的。

因为看了一些关于JAVA的反射技术的应用,忽然想到DELPHI的RTTI也很强,于是试着拿数据集下手,用RTTI来实现它的对象化。用了两个晚上时间就搞定了(要不是因为开始时搞错对象--基类用了TObject,其实应该是用TPersistent才对),果然很简单。

假设有一个ADODataSet控件,连接罗斯文数据库,SQL为:

select * from Employee

现在要把它的内容中EmployeeID, FirstName, LastName三个字段显示到ListView里。我通过RTTI实现了一个数据集代理类,使得代码得到大大的简化(这两天争取把结果整理出来另外撰文说明)。其结果大致如下:

Type
  TPDSEmployee = class( TMProxyDataSet )
  published
    Property EmployeeID : Integer Index 0 Read GetInteger Write SetInteger;
    Property FirstName : String Index 1 Read GetString Write SetString;
    Property LastName : String Index 2 Read GetString Write SetString;
  End;
...
emp := TPDSEmployee.Create( ADODataSet1 );
While emp.ForEach Do
    With ListView1.Add Do
    Begin
      Caption := IntToStr( emp.EmployeeID );
      SubItems.Add( emp.FirstName );
      SubItems.Add( emp.LastName );
    End;
emp.Free;

对比传统的实现代码,好处是显尔易见的。

但是当我实现出这个TMProxyDataSet类后,不禁感到痛心疾首,这个我早在三年前就应该想到的。

三年前DELPHI6刚推出时,我就发现它的SOAP功能是通过DELPHI强大的RTTI来实现的,我为什么当时没有想到去深入研究一下DELPHI的RTTI呢?

这次要不是因为看到了一些JAVA的资料,我可能还是想不到,所以多了解一些别的语言是很重要的事。特别是最近以来,动态语言越来受到关注,虽然它们在性能上不能跟原生开发相比,但在很多的开发思想上,具有重要的启发意义。

在做了这个东东以后,我才意识到,DELPHI其实是所有原生开发语言中,动态性最高的,并不比基于虚拟机的JAVA和C#低多少。只是长期在做RAD的开发,没有体会到而已。程序员在RAD下被惯坏了。

做完这个,我打算下一步再试试用RTTI实现对象的XML持久化(基本上就是抄袭一下DELPHI本身的SOAP实现代码-_-|||)。这个思路应该会比我原先用的XML Data Binding要方便很多,至少不用再去写那个麻烦的XML Schema了。

BTW:以前没有太关注RTTI,效率恐怕是其中最重要的一个原因,但是现在看来,跟虚拟机语言甚至动态语言相比,DELPHI作为原生应用开发,这点RTTI效率损失其实根本没有想像中那么大的影响。换来开发效率的大大提高还是很值得的。

 

 

 

 

type
  TDBproxy = Class (TPersistent)
  private
    fDataSet:TDataSet;
  public
    constructor Create(ADateSet: TDataSet);
    function ForEach : boolean;
  end;

implementation

{ TDBproxy }

constructor TDBproxy.Create(ADateSet: TDataSet);
begin
  Assert( assigned(ADateSet));
  fDataSet:= ADateSet;
end;

function TDBproxy.ForEach: boolean;
var
  I: Integer;
begin
  result := false;
  if fDataSet.eof then
    exit;
  fDataSet.Next;
  for I := 0 to fdataset.FieldCount -1 do
    SetPropValue(self,fDataSet.Fields[i].FieldName,fDataSet.Fields[i].AsVariant);
  result := true;
end;

发表于 @ 12:01 | 评论与反馈 (0)

信息主题: 上个星期六听UML和OOAD的心得,这是第一天的
信息作者: Water-E
发表时间: 2005-01-28 10:30:32
阅读次数: 39
信息内容:
OOAD和UML培训心得

今天在中创软件听了邵维忠老师关于OOAD和UML的培训,邵老师讲的太精彩了,预先一些在UML学习过程中困扰我好久的问题,都被邵老师一一点破,回来细细品味了一下确实收益非浅。

这四天培训原本的课程安排是:
1.OOAD的原理和历史
2.UML的原理和概念
3.OOA
4.OOD
先简单复述一下今天邵老师今天所讲课程:

上午的课程:

今天上午的课程讲述了OOAD的原理和历史,邵老师把类、对象、抽象、继承、基类、派生类、封装、消息、聚合、关联、多态的概念又细细讲了一遍,这些概念虽然都是些了熟于胸的内容,但因为邵老师讲的都很生动、并且重点也十分突出听起来还是有很大收获。其中老师重点提了一下对于封装不同的OO语言不相同的做法,对于Smalltalk这种纯OO的语言中强调外部对象不能访问内部数据,但这样同样带来的是编程麻烦、影响执行效率的问题,而现在一般的混合型OOPL语言(C++\Delphi\Java)大多采用不强调严格封装、实行可见性控制的方法,保证了灵活性,相当于把选择权又重新交还给程序员,即可以使用严格的封装有的时候也可以灵活的访问数据。讲的继承的时候我比较感兴趣,因为邵老师讲了一下使用单继承的Smalltalk和使用多继承的c++及多继承可能产生的问题,而没有讲多继承的另一种实现形式“接口”,现在流行的设计语言如Delphi\java\c#等都使用单继承+接口的实现方式,这样既避免了继承结构的混乱和命名冲突,又在原有基础上实现了模块间的契约调用。这样的设计方式在vcl、jdbc等类库中都体现了很好扩展性,并且在经典的设计模式中也有很多体现。对于这个问题我在课下还专门询问了一下老师,邵老师解答说接口不属于OOAD的基本范畴,属于是语言和UML扩展的概念。并且邵老师认为接口实现的意义很有限,并且在很多地方还会影响效率。但在我们实际开发中能否正确使用接口经常被认为是初学者和高手之间的差别,这可能也是因为学术大家和基层工作者所看问题角度不同引起的,当然这也是个仁者见仁,智者见智的问题了。

在上午的课程中老师还着重强调了一下“关联”关系,好像是因为最近在国内很多书籍中对“关联”的描述不是很准确,邵老师用集合学上的一个概念来描述“关联”关系:对于集合 A{A1,A2,A3......AN}和集合B{B1,B2,B3,......BM}的笛卡尔积A*B集合中,任意元素如果提供了被开发领域中使用的一组有意义的信息则定义为一个关联。虽然读起来绕口但理解起来也不困难。同时邵老师也提出了现在在UML使用过程中对关联关系认识上的误区:“认为任何2个类存在关联关系才会有消息”,其实即使2个类不存在关联关系也可能有消息传递。

下午的课程:

在下午的课程中老师讲了UML相关的课程,这部分课程中老师讲了很多书本上没有的观点和内容也是我收获最大的一部分。首先老师讲了一下UML的历史,需要说明的是前面UML的这段历史对于后面理解UML一些奇怪而错误的设定有很大帮助。

先来简单复述一下UML的历史(以下内容摘录自OMG UML修订任务组和OMG分析设计平台任务组联合主席Cris Kobryn于1999年10月在《COMMUNICATION OF THE ACM》上发表<UML 2001:标准化的《奥德赛》史诗>[蒋严冰老师 邵维忠老师  编译]):
------------
早在1995年,Gray Booch和Janes Rumbaugh将他们的面向对象建模方法统一为Unified Method V0.8。一年之后Ivar Jacobson加入其中,共同将该方法统一为二义性较少的UML 0.9。同时,这三位杰出的方法学家被称为“三友(Three Amigos)”。

很快用户也认识到可对软件系统进行可视化、描述、构造和文档化的通用建模语言所带来的益处。他们充满激情地将这种语言的早期草案应用于不同的领域。受用户强烈需求的驱动,建模工具厂商也很快在它们的产品中加入了对UML的支持。

与此同时,UML成了实际上的工业标准。1996年,一个由建模专家组成的国际性队伍“UML伙伴组织”开始同“三友”一起工作,计划将UML提议作为OMG的标准建模语言。

1997年1月,伙伴组织向OMG提交了最初的提案UML 1.0。经过了九个月的紧张修订,于1997年9月提出了最终提案UML 1.1,这个提案在1997年11月被OMG正式采纳为对象建模标准。

有必要指出的是,由于比较仓促地通过了OMG的提交过程,尽管语言的基层结构和大部分上层结构是合理的,UML还是容忍了一些不尽如人意的负面因素:活动图的语义及表示法不完整;标准元素臃肿,其中有些元素是为了满足不同的、相互竞争的方法门派的需求而草率加入的,许多标准元素语义贫乏,而且命名和组织也不一致;结构混乱,所提交的规范并没有达到提交者预期的目标——用一种严格的元模型方法实现4层元模型结构,相反使用了一种实用但不精确的、松散的元模型方法,不利于UML同其他OMG规范的结合,比如与MOF(Meta Object Facility)的结合。

-------------
由上面可以看出UML虽然吸收了百家之长但并没有完全的进行取舍进行融会贯通,我觉得这也是自己在UML学习中经常走向歧途的原因之一。同时老师还强调UML虽然是现在软件建模中实际的标准但严格意义上来讲只是通过OMG批准的规范(specification)还不是严格意义上的标准(standard)。

讲完UML的历史后老师以UML1.4为参考从整体上讲述了UML规范的内容。UML1.4的规范分为6个部分:
1.概要
2.语义
3.表示法指南
4.外扩范例:(指针对不同领域的扩展--注:这部分笔记记的不是太清楚)
5.模型交换 a, CORBA的设施接口IDL b, XMI DTD规范
6.对象约束语言规范(OCL)

接下来老师讲了UML的语言体系结构,这部分应该是今天课程中最绕口最不好理解的部分了,这个元-元模型图我以前在书上看过好几次解释也看了不少,都是囫囵吞枣过去的,这次经过邵老师悉心讲解才知道其真正的作用。四级元模型是OMG为面向对象方法所规定的一个体系结构,UML符合这个规范。对于四级元模型:

M3级别为元-元模型:它是定义建模语言的语言,相当于MOF
M2级别为元模型:它就是我们所说的建模语言也就是UML
M1级别为模型:这部分是由我们开发者使用的也就是UML所建立的模型
M0级别为用户对象:这部分属于是系统用户层次,属于是模型所描述的实体。


讲完这个让大家头大的问题,下面的关于“元模型构造物”的内容理解起来依然不轻松,元模型构造物分为抽象构造物和具体构造物,具体构造物是指我们开发者在实际建模过程中使用到的元素,抽象构造物是为了更进一步描述UML描述具体构造物而抽象出来的构造物。
数据类型、类、接口、构件、节点这几个可以被分类实体化元素继承自抽象元模型构造物Classifier(类目);关联、泛化、依赖继承自“关系”;关系和Classifier同时又继承自可泛化元素。

完成这部分内容后,剩余的内容就轻松了很多,接下来老师讲了UML表示法和UML图中常用到的元素和UML的扩充机制:
UML图中的元素:String(字符串)、name(名字)、label(标签)、keyword(关键字)、Expression(表达式)、note(注释)、package(包)
UML的扩展机制是UML的一个亮点,也是因为它扩展机制保证了它的流行和可用性:
1. 约束{OCL}
2. 注释:文字说明
3. 元素特征:属性 {关键词=值}
4. Stereotypes(衍型):这部分的扩展是UML扩展功能中最有用的一部分, 它可以看作是原有类的一个子类,它在属性、关系等方面与原有元素相同,但用途更加具体。(上次pinxue老师的培训中也很强调了这个特性)
在UML的2.0中扩展将更加广泛,可以使用元-元模型定义元模型构造器。

在UML1.4中提供了9种不同的图,这些图从不同的视角对系统进行建模。
1. 类图:(在UML中最常用到图),仅用来表示静态类属性(此部分需要细化)
2. 对象图:(用处十分有限),对象图和类图有所重复,使用它会使得抽象的层次不明显,模型和程序对应得好才是好的建模语言。在UML修订过程中层考虑去掉对象图,但UML2.0版本还在保留,在GB-OOAD规范中将不使用该对象图。
3. 用况图(非常有用的图,特别是用在收集需求方面)可以规范描述需求,对于Include关系和Extend关系,Include表示一定会触发,Extend表示可能会触发。而在实际开发过程中,对于Include和Extend的处理方法都是一样的,可以更进一步抽象。对于用况的泛化关系,这个关系本身作用并不明显不严格不建议使用。用况图不仅仅是图形更重要的是文字描述。
4. 顺序图:(比较有用)表示的很清楚但只能表述很小的局部内容,[消息和激发]可以直接理解为消息
5. 协作图(最没用的图之一),因为类于类之间关系在类图中已经表示了,所以这个图得意义更加有限。
6. 状态图:意义有限,不过在某些特殊领域可能会用到
7. 活动图(比较有用)在结构化程序中可以代替流程图使用
8. 构件图:在1.4中相当于模型图,在2.0中有进一步改进
9. 部署图:

邵老师对UML的几个图和图形元素作了很详细的点评,这部分结合我们原先实际工作的情况做了下对比确实收获不小。



心得:
1. 原先我们在工作中一般使用类图、use case图、顺序图比较多,在有些判断流程很多的地方也会用活动图,当时看到UML提供了这么多的图和元素我们在实际项目中却用不上,都认为是自己对UML认识还不够,还不能领会真正用途,现在才知道其他的几个图对于我们普通开发者好像的确是没有什么用。
2. 对UML的历史有了进一步了解,原来称呼UML是一种OOAD的方法也是有一定道理的
3. 对于初学者UML难于学习一部分原因是因为其中涵盖的范围广泛,不同方法门派观点的杂糅以及结构混乱也是原因之一,UML有很多地方难于理解应该也是缘由此。
4. 原先和同事们为分辨一个use case是Extend还是Include经常会讨论半天,现在才知道究竟是那个关系并不重要,因为从更高的抽象角度看它们都是一样的,
5. 因为UML抽象化程度非常高,对于很多新名词的翻译上确实有很大难度,初学者看些原版书或是由国内学者消化吸收后自己写出来的书已经对学习有帮助。
6. 原先在学习UML总是觉得UML是十分高深和天书有的一比,经过老师点播后发现使用UML对于我们开发人员并不算困难,对于UML图只要学会适当裁剪取舍即可。
7. 对于临近下课一位同学问的在需求分析中是使用USE CASE图还是使用自然语言的描述,老师的解答是2者都要。事实上在Rational SUIT中已经提供了类似的解决方案,使用Requisite Pro需求管理工具,可以将rose中画的use case转换成自然语言描述的需求,并对需求的实现进行跟踪,看这个需求在设计阶段是不是被设计,同样实现阶段是否被实现,不过由于其关联性太强,在一般公司需求跟踪工作很难完成,不过use case转换成自然语言的工作是很简单的。
8. 我在学习UML过程中,在思考能否依靠工具来辅助软件开发,我的想法是在需求阶段,case软件可以帮助分析收集需求(由开发人员识别use case、actor),相应得可以生成需求文档,开发人员根据需求做出相应的设计文档,设计文档中要保证需求里面要求的功能都被设计到,并且可以根据设计中的类图生成编码中的类编码框架,并且保证设计中的内容都能被实现,同时这个CASE 软件可以对软件开发过程的变更进行跟踪,比如需求做出了变更则CASE软件同样提醒开发人员那些设计需要变更,同样设计改变后也会降实现部分的代码自动修改,实现一个完整的需求跟踪矩阵。同时这个CASE软件还能对变更、版本和工程进度作管理。上面说的这个软件的很多功能在Rational SUIT已经实现,但真正使用的意义并不是太大,主要是因为使用起来过于繁琐,且ROSE对我们当时使用的开发语言DELPHI支持不好。
9. 我尝试过很多的建模工具,发现最好用的是www.sparxsystems.com.au出品的Enterprise Architect ,价格和大小只有ROSE的1/10, 功能比rose更加完善,带有需求管理、估算等几个有特色的功能,并且能够支持UML2.0。
 
 
接口应该是独立语言的,Java中的接口,实际上是纯虚类的别名,算不上真正意义的接口。接口是用来实现系统可插入性的保障,没有了接口,也就无法实现可插入性。所以一般认为接口是OOD范畴,而不是OOP范畴。其实讲接口,应该重点讲依赖倒转原则。

多继承和单继承问题,是OOPL届一直争论不休的问题,这方面两派都自有说法。我个人认为多继承还是有必要的,而且单继承+接口继承并不等于多继承。

没有提到泛型比较可惜,继承是OOP的基石,而泛型是OOD的基石。

Use Case应该是文本为主,图形只是辅助手段。
发表于 @ 11:52 | 评论与反馈 (1)