• Thứ Hai, 15/11/2010 13:19 (GMT+7)

    Trả lời thư bạn đọc

    BBT
    Mục giải đáp thắc mắc của bạn đọc do TS. Nguyễn Văn Hiệp phụ trách.

    Q: Xin hướng dẫn sử dụng Foxpro for dos xuất dữ liệu dùng font VNI-DOS sang Excel và chuyển sang mã Unicode.

    A: Yêu cầu của bạn gồm 2 vấn đề chính cần giải quyết:

    1. Copy các record dữ liệu từ file *.dbf sang 1 worksheet Excel. File *.dbf là 1 bảng (table) dữ liệu, worksheet Excel cũng là 1 bảng dữ liệu. Do đó việc chuyển thông tin từ file *.dbf sang worksheet Excel là hoạt động copy dữ liệu từ table này sang table khác. Bạn có thể lập trình dùng các đối tượng ADO để thực hiện hoạt động này. Cách đơn giản nhất là dùng trực tiếp Excel như sau: chạy Excel, chọn menu File.Open để mở file *.dbf và hiển thị lên 1 worksheet Excel. Sau đó, chọn menu File.Save As để lưu lại theo định dạng *.xls.

    2. Chuyển mã các chuỗi văn bản trong bảng dữ liệu từ bảng mã này sang bảng mã khác (cụ thể là từ VNI 1 byte sang Unicode). Bạn có thể dùng các ứng dụng chuyển mã tiếng Việt sẵn có trên thị trường để chuyển mã tiếng Việt trực tiếp trong worksheet Excel.

    Lưu ý, do bảng mã tiếng Việt VNI-DOS (và một số bảng mã tiếng Việt cũ khác) có dùng một số mã ký tự điều khiển làm ký tự tiếng Việt nên một số ứng dụng bị xử lý sai. Do đó để giải quyết tổng quát và triệt để vấn đề chuyển mã tiếng Việt, chúng tôi có viết 1 đối tượng COM cung cấp các hàm chức năng để chuyển mã tiếng Việt từ bất kỳ bảng mã nào sang một bảng mã khác. Bạn có thể liên hệ với tòa soạn để copy đối tượng này (file bktrans.dll) về cài vào máy và sử dụng. Qui trình cài đặt đối tượng COM vào máy như sau:

    - Copy file bktrans.dll vào thư mục thích hợp (thí dụ c:\MyCOM).

    - Tạo icon shortcut trên màn hình desktop của trình đăng ký components bằng cách ấn phải chuột trên màn hình desktop, chọn option New.Shortcut, duyệt và chọn file c:\windows\system32\regsvr32.exe để tạo icon shortcut cho nó.

    - Chạy tiện ích duyệt hệ thống file, tìm và hiển thị nội dung thư mục c:\MyCOM, thay đổi kích thước/dời vị trí cửa sổ hiển thị thư mục sao cho thấy được icon shortcut của trình đăng ký component, chọn file bktrans.dll, drag nó vào icon shortcut của trình đăng ký để đăng ký nó vào Windows.

    - Sau khi đã đăng ký thành công, bạn có thể dùng bất kỳ môi trường lập trình nào (VB, VC++,...) để lập trình ứng dụng và dùng đối tượng Bktrans vừa đăng ký y như dùng các đối tượng COM khác.

    Sau đây chúng tôi xin trình bày qui trình điển hình để xây dựng 1 ứng dụng bằng VB 6.0 đọc bảng dữ liệu từ file *.dbf, chuyển mã tiếng Việt từ mã VNI-DOS sang mã Unicode cho bất kỳ field chuỗi nào rồi ghi kết quả lên 1 worksheet Excel:

    1. Chạy VB 6.0, tạo Project mới thuộc loại "Standard EXE" (loại Project mặc định có 1 Form giao diện rỗng ban đầu).

    2. Chọn menu Project.References để hiển thị cửa sổ References. Duyệt tìm và chọn mục BkTrans 1.0 Type Library để "add" thành phần COM phục vụ chuyển mã tiếng Việt vào Project. Tương tự, duyệt tìm và chọn mục Microsoft ActiveX Data Objects 2.x Library để "add" thành phần COM phục vụ truy xuất database vào Project.

    3. Chọn menu Project.Components để hiển thị cửa sổ Components. Duyệt tìm và chọn mục Microsoft Common Dialog Control 6.0 để "add" điều khiển phục vụ duyệt hệ thống file vào Project.

    4. Thiết kế Form ứng dụng theo hình sau, gồm có 5 label, 3 textbox, 2 combobox, 3 button và 1 CommonDialog:

    Đặt tên cho 3 textbox là txtDBFFile, txtExcelFile, txtWorksheet, tên cho 3 button là btnDBFFile, btnExcelFile, btnStart, tên cho 2 combobox là cbSourceCode, cbDestCode, tên cho CommonDialog là FileDialog.

    5. Ấn kép chuột vào button btnDBFFile để tạo thủ tục xử lý sự kiện Click chuột trên nó, tương tự tạo thủ tục xử lý Click chuột cho 2 button còn lại và cho 2 Combobox rồi viết code VB 6.0 sau đây:

    Option Explicit
    'khai báo các biến cần dùng
    Private srcid As Integer
    Private dstid As Integer
    Private VietLibCOM As New BKTRANSLib.BKTRANSLib

    'thủ tục Click button chọn file DBF
    Private Sub btnDBFFile_Click()
    FileDialog.ShowOpen
    txtDBFFile.Text = FileDialog.FileName
    End Sub

    'thủ tục Click button chọn file Excel
    Private Sub btnExcelFile_Click()
    FileDialog.ShowOpen
    txtExcelFile.Text = FileDialog.FileName
    End Sub

    'thủ tục Click button bắt đầu chuyển mã & chuyển định dạng
    Private Sub btnStart_Click()
    'khai báo các biến cần dùng
    Dim Connection1 As ADODB.Connection
    Dim RecordSet1 As ADODB.Recordset
    Dim Connection2 As ADODB.Connection
    Dim RecordSet2 As ADODB.Recordset
    Dim Command2 As ADODB.Command
    Dim path As String, TableName As String
    Dim strSQL As String, strbuf As String
    Dim sfldbuf As String, dfldbuf As String
    Dim i As Integer, j As Integer
    Dim fStart As Integer, kq As Long
    Dim fld As Variant
    'xác định đường dẫn và file DBF
    i = 1
    Do
    j = InStr(i, txtDBFFile.Text, "\", vbBinaryCompare)
    If (j <> 0) Then
    i = j + 1
    End If
    Loop While j <> 0
    'xác định đường dẫn
    path = Mid(txtDBFFile.Text, 1, i - 1)
    'xác định tên file DBF
    TableName = Mid(txtDBFFile.Text, i)
    'Tạo connection tới database nguồn
    Set Connection1 = New ADODB.Connection
    Connection1.Open "Provider=MSDASQL;DRIVER=Microsoft FoxPro VFP Driver (*.dbf);SourceType=DBF;SourceDB=" & path & ";"
    'Tạo recordset chứa các record của table nguồn
    Set RecordSet1 = New ADODB.Recordset
    RecordSet1.Open TableName, Connection1, adOpenStatic, adLockReadOnly, adCmdTable
    'Tạo connection tới database đích
    Set Connection2 = New ADODB.Connection
    Connection2.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & txtExcelFile.Text & ";Extended Properties=Excel 8.0;"
    'Tạo command làm việc với database đích
    Set Command2 = New ADODB.Command
    Command2.ActiveConnection = Connection2
    'xây dựng lệnh SQL tạo Table đích
    strSQL = "CREATE TABLE " & txtWorksheet.Text & " ("
    'duyệt tìm từng field của table nguồn
    fStart = 1
    For Each fld In RecordSet1.Fields
    'tìm tên và kiểu của field
    Select Case fld.Type
    Case 2
    strbuf = "Integer"
    Case 3
    strbuf = "Long"
    Case 5
    strbuf = "Currency"
    Case 6
    strbuf = "Double"
    Case 11
    strbuf = "Logical"
    Case 202
    strbuf = "Text"
    Case 203
    strbuf = "Text"
    Case 7
    strbuf = "Date"
    Case 135
    strbuf = "Date"
    Case 129
    strbuf = "Text"
    Case 131
    strbuf = "Integer"
    Case 133
    strbuf = "Date"
    Case Else
    MsgBox "Type với mã " & fld.Type & " chưa được xử lý!!!"
    End Select
    If fStart Then
    strSQL = strSQL & fld.Name & " " & strbuf
    fStart = 0
    Else
    strSQL = strSQL & ", " & fld.Name & " " & strbuf
    End If
    Next fld
    strSQL = strSQL & ")"
    'Xóa table trên database đích nếu có rồi
    'Command2.CommandText = "DROP TABLE " & txtWorksheet.Text
    'Command2.Execute
    'Tạo mới table trên database đích
    Command2.CommandText = strSQL
    Command2.Execute
    'Tạo recordset chứa các record của table đích
    Set RecordSet2 = New ADODB.Recordset
    RecordSet2.Open txtWorksheet.Text, Connection2, adOpenKeyset, adLockOptimistic, adCmdTable
    'duyệt chuyển mã và copy từng record
    While Not RecordSet1.EOF
    'tạo mới record
    RecordSet2.AddNew
    For i = 0 To RecordSet1.Fields.Count - 1
    'nếu field i là chuỗi thì chuyển mã
    If (RecordSet1.Fields(i).Type = 129) Or (RecordSet1.Fields(i).Type = 202) Or (RecordSet1.Fields(i).Type = 203) Then
    On Error GoTo AssignIt
    sfldbuf = RecordSet1.Fields(i).Value
    If Len(sfldbuf) <> 0 Then
    kq = VietLibCOM.TransStr(srcid, dstid, sfldbuf, dfldbuf)
    RecordSet2.Fields(i).Value = dfldbuf
    Else: GoTo AssignIt
    End If
    Else
    'nếu không thì chỉ copy dữ liệu
    AssignIt:
    RecordSet2.Fields(i).Value = RecordSet1.Fields(i).Value
    End If
    Next i
    'lưu lại record lên table đích
    RecordSet2.Update
    'di chuyển đến record kế tiếp
    RecordSet1.MoveNext
    Wend
    'đóng các đối tượng sử dụng lại
    RecordSet1.Close
    Connection1.Close
    Connection2.Close
    End Sub

    'thủ tục Click chọn mã tiếng Việt đích
    Private Sub cbDestCode_Click()
    dstid = cbDestCode.ListIndex
    End Sub

    'thủ tục Click chọn mã tiếng Việt gốc
    Private Sub cbSourceCode_Click()
    srcid = cbSourceCode.ListIndex
    End Sub

    'thủ tục khởi tạo ban đầu cho ứng dụng
    Private Sub Form_Load()
    Dim i As Integer
    Dim s As String
    Dim ret As Integer
    Dim cnt As Integer
    'xóa trắng nội dung các đối tượng hiển thị
    txtDBFFile.Text = ""
    txtExcelFile.Text = ""
    txtWorksheet.Text = ""
    cbSourceCode.Clear
    cbDestCode.Clear
    'khởi động đối tượng chuyển mã
    ret = VietLibCOM.Init()
    'tìm số bảng mã được phép xử lý
    cnt = VietLibCOM.GetCodeCount()
    'hiển thị chúng vào 2 combox để user chọn lựa
    For i = 0 To cnt - 1
    VietLibCOM.GetCodeName i, s
    cbSourceCode.AddItem s
    cbDestCode.AddItem s
    Next i
    End Sub

    6. Chọn menu Run.Start để chạy thử ứng dụng, chọn file DBF gốc, chọn file Excel chứa kết quả, chọn mã tiếng Việt gốc, chọn mã tiếng Việt đích, nhập tên worksheet chứa kết quả, chọn button "Bắt đầu copy và chuyển mã file DBF". Sau đó chạy Excel và mở xem thử nội dung file Excel kết quả.

    Lưu ý chương trình trên có thể truy xuất bảng dữ liệu của bất kỳ database server nào (FoxPro, Access, Excel, MySQL, SQL, Oracle,...). Bạn chỉ cần hiệu chỉnh chuỗi ConnectionString miêu tả database cần truy xuất cho phù hợp với định dạng database cần truy xuất.

    Bạn có thể liên hệ với tòa soạn để copy Project VB 6.0 của ứng dụng chuyển mã (có tên là VBTransDataTable) và file bktrans.dll chứa đối tượng COM phục vụ chuyển mã tiếng Việt.

    Q: Xin hướng dẫn lập trình VB6 kết nối với Excel và lấy dữ liệu của một sheet có tên là hoso, các thông tin về hồ sơ cá nhân của sheet hoso được hiển thị trên MS Flexgrid và ghi vào file *.mdb. Sheet hoso gồm: hoten, namsinh, diachi.

    A: Đối tượng MSFlexGrid cho phép hiển thị và hiệu chỉnh dữ liệu dạng bảng 2 chiều, nó có thể được nối kết với 1 bảng dữ liệu của 1 database nào đó (Excel, Access, SQL Server,…) bằng cách khai báo trực quan tại thời điểm thiết kế hay bằng cách viết code thực thi động. Cách dễ dàng nhất để dùng MSFlexGrid hiển thị và hiệu chỉnh dữ liệu của bảng dữ liệu Excel hay Access là thiết kế trực quan đối tượng này cùng đối tượng Data Control trong 1 Form ứng dụng, nối kết nó với đối tượng Data Control, khai báo thông tin bảng dữ liệu cần làm việc cho Data Control biết. Tuy nhiên khả năng của đối tượng Data Control trong môi trường VB 6.0 rất hạn chế, nó chỉ có thể hoạt động tốt với các bảng dữ liệu của file Excel và Access dùng định dạng rất cũ. Hơn nữa, bản thân MSFlexGrid không cung cấp các tác vụ phục vụ việc chuyển đổi dữ liệu từ Excel sang Access hay ngược lại. Để khắc phục các nhược điểm trên của đối tượng MSFlexGrid, bạn nên dùng các đối tượng "Automation" của Excel và Access để phục vụ bài toán của mình, cụ thể bạn hãy dùng đối tượng Excel.Application để mở file Excel, xem và hiệu chỉnh thông tin theo yêu cầu, sau đó dùng đối tượng Access.Application để mở file Excel, đọc worksheet dữ liệu đã có, chuyển định dạng và lưu kết quả lên thành 1 bảng dữ liệu Access. Qui trình điển hình để viết ứng dụng VB 6.0 giải quyết yêu cầu của bạn như sau:

    1. Chạy VB 6.0, tạo project mới dạng "Standard EXE", sau khi form ứng dụng trống hiển thị, bạn vẽ 2 button, hãy hiệu chỉnh thuộc tính cho 2 button như sau:

    - button thứ nhất: Name =btnDoc, Caption=Xem/sửa worksheet.

    - button thứ hai: Name = btnLuu, Caption=Lưu lên Access.

    2. Chọn menu Project.References để hiển thị cửa sổ References, duyệt tìm và đánh dấu chọn vào 2 mục "Microsoft Access x.0 Object Library" và "Microsoft Excel x.0 Object Library" rồi chọn button OK để "add" các đối tượng Automation xử lý Excel và Access vào Project của ứng dụng.

    3. Hiển thị lại cửa sổ thiết kế Form ứng dụng, ấn kép chuột vào từng button để tạo thủ tục xử lý sự kiện cho từng button. Khi cửa sổ soạn code hiển thị, bạn viết code cho từng thủ tục như sau:

    'thủ tục xử lý button btnDoc
    Private Sub btnDoc_Click()
    'định nghĩa biến miêu tả ứng dụng Excel
    Dim ExcelApp As Excel.Application
    'tạo ứng dụng Excel
    Set ExcelApp = CreateObject("Excel.Application")
    'mở file Excel chứa worksheet cần làm việc
    ExcelApp.Workbooks.Open "c:\test.xls"
    'hiển thị cửa sổ Excel để người dùng làm việc
    ExcelApp.Visible = True
    'khi hoàn thành, người dùng sẽ thực hiện menu File.Save
    End Sub

    'thủ tục xử lý button btnLuu
    Private Sub btnLuu_Click()
    'định nghĩa biến miêu tả ứng dụng Access
    Dim Accessapp As Access.Application
    'tạo ứng dụng Access
    Set Accessapp = CreateObject("Access.Application")
    'mở file Access sẽ chứa bảng tính Excel
    Accessapp.OpenCurrentDatabase "c:\test.mdb"
    'lưu bảng Sheet2 thành bảng Access có tên là TestTable
    Accessapp.DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, "TestTable", "c:\test.xls", True, "Sheet2!"
    'dừng ứng dụng Access
    Accessapp.Quit
    End Sub

    4. Chạy thử ứng dụng, ấn chuột vào button btnDoc để hiển thị ứng dụng Excel, xem/soạn thảo dữ liệu cho bảng tính có tên là "Sheet2", hàng trên cùng nên chứa tiêu đề các field dữ liệu (hoten, namsinh, diachi), mỗi hàng kế tiếp sẽ miêu tả 1 dữ liệu cụ thể. Sau khi hoàn thành soạn thảo nội dung của bảng tính, chọn menu File.Save để lưu kết quả lên file rồi dừng Excel. Bây giờ bạn chọn button btnLuu, ứng dụng sẽ kích hoạt Access chạy tự động, yêu cầu Access mở file database có tên là "c:\test.mdb", đọc bảng Sheet2 từ file Excel "c:\test.xls" rồi lưu thành bảng dữ liệu Access có tên là "TestTable".

    Q: Xin hướng dẫn lập trình VB .Net làm form trong suốt nhưng các control trên form như: textbox, button hay các control khác thì không.

    A: Mỗi form của VB .Net đều có thuộc tính Opacity để miêu tả độ trong suốt của form: 0 (%) miêu tả form trong suốt hoàn toàn, 100 (%) miêu tả form bình thường. Tuy nhiên thuộc tính này của form sẽ được thừa kế mặc định bởi các điều khiển nằm trong form: form trong suốt hoàn toàn thì các điều khiển trong form cũng trong suốt hoàn toàn, trong trường hợp này việc tương tác với form bởi người dùng rất khó khăn vì người dùng không thể xác định vị trí của từng điều khiển trong form để làm việc.

    Nếu muốn chỉ có form (vùng nền) trong suốt, còn các điều khiển khác nằm trong form hiển thị bình thường, bạn cần lập trình để giải quyết vấn đề này. Cụ thể, bạn chỉ cần viết đoạn code VB .Net sau vào trong class đặc tả form của bạn (nằm đầu tiên trong class form):

    'khai báo các hàm API cần dùng
    Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA"(ByVal hwnd As Integer, ByVal nIndex As Integer) As Integer
    Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA"(ByVal hwnd As Integer, ByVal nIndex As Integer, ByVal dwNewLong As Integer) As Integer
    Private Declare Function SetLayeredWindowAttributes Lib "user32" (ByVal hwnd As Integer, ByVal crKey As Integer, ByVal bAlpha As Byte, ByVal dwFlags As Integer) As Integer
    'khai báo các hằng gợi nhớ cần dùng
    Private Const GWL_STYLE As Short = (-16)
    Private Const GWL_EXSTYLE As Short = (-20)
    Private Const WS_EX_LAYERED As Integer = &H80000
    Private Const LWA_COLORKEY As Short = &H1s
    Private Const LWA_ALPHA As Short = &H2s
    'thủ tục khởi tạo Form
    Private Sub Form1_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load
    'thiết lập nền của form về xanh dương
    Me.BackColor = System.Drawing.Color.Blue
    SetWindowLong(Me.Handle.ToInt32, GWL_EXSTYLE, GetWindowLong(Me.Handle.ToInt32, GWL_EXSTYLE) Or WS_EX_LAYERED)
    'chuyển vùng xanh dương về trong suốt
    SetLayeredWindowAttributes(Me.Handle.ToInt32, System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Blue), 0, LWA_COLORKEY)
    End Sub

    Q: Tôi làm Java ME trên NetBeans, tạo 1 DateField:
    df = new DateField("Thoi Gian:",DateField.TIME);
    df.setDate(new Date());
    thời gian hiển thị bị lệch 7 tiếng so với thời gian hiện tại. Làm sao để có thời gian đúng? 

    A: Chúng tôi đã kiểm tra hiện tượng lệch giờ như bạn miêu tả trên môi trường NetBeans 6.9 dùng JDK 1.6, kết quả là đối tượng DataField trong package "javax.microedition.lcdui" không hoạt động tốt ở chế độ DateField.TIME. Nếu dùng chế độ DateField.DATE hay DateField.DATE_TIME thì đối tượng DataField hoạt động đúng, không có hiện tượng lệch giờ như bạn nói. Sau đây là source code của 1 ứng dụng mobile đơn giản, nó sẽ hiển thị 1 đối tượng DataField để cho phép người dùng xem/hiệu chỉnh thời gian và button Start để hiển thị giờ hiện hành trên thiết bị.

    // mã nguồn java J2ME của 1 ứng dụng mobile đơn điản
    import java.util.*;
    import javax.microedition.lcdui.*;
    import javax.microedition.midlet.*;

    public class DateAndTime extends MIDlet implements CommandListener{
    private Display disp;
    private Date d;
    Calendar c = Calendar.getInstance();
    String time;
    private DateField currentDate;
    private Command start, exit;
    private Form form;
    private int index;

    public DateAndTime(){
    d = new Date();
    form = new Form("Data and Time");
    start = new Command("start", Command.SCREEN, 1);
    exit = new Command("Exit", Command.EXIT, 0);
    currentDate = new DateField("Thoi gian :",DateField.DATE_TIME,TimeZone.getDefault());
    currentDate.setDate(d);
    }

    public void startApp(){
    form.append("CURRENT TIME IS: ");
    index = form.append(currentDate);
    form.addCommand(start);
    form.addCommand(exit);
    form.setCommandListener(this);
    disp = Display.getDisplay(this);
    disp.setCurrent(form);
    }

    public void pauseApp(){}
    public void destroyApp(boolean uncond){}
    public void commandAction(Command cmd, Displayable s){
    if (cmd == exit){
    notifyDestroyed();
    } else if (cmd == start){
    d = new Date();
    c.setTime(d);
    time = c.get(Calendar.HOUR_OF_DAY) + ":" +c.get(Calendar.MINUTE)
    + ":" + c.get(Calendar.SECOND);
    form.append("" + time+"\n");
    }
    }
    }

    Q: Xin hướng dẫn viết chương trình bằng NetBean xuất ra file Excel, trong đó một số vị trí ô hay cột không cho thay đổi.

    A: Bạn có thể thiết lập một số khả năng bảo vệ (Protection) cho toàn bộ workbook (file *.xls) hay cho từng worksheet Excel. Tuy nhiên chức năng "Protection" của Excel không cho phép bạn bảo vệ từng cell riêng biệt theo chế độ riêng biệt. Để khắc phục vấn đề này, bạn có thể viết code VBA tự quản lý quá trình tương tác giữa người dùng và máy tính. Sau đây là qui trình soạn thảo bảng tính mà khi dùng lại nó, người dùng sẽ không được phép thay đổi nội dung một số cell qui định trước:

    1. chạy Excel, mở/tạo file Excel chứa bảng tính cần xử lý (thí dụ bảng Sheet1).

    2. soạn thảo và chỉnh dạng nội dung ban đầu của bảng tính.

    3. chọn menu Tools.Macro.Visual Basic Editor để hiển thị cửa sổ soạn code VBA cho file Excel hiện hành.

    4. ấn kép chuột vào mục "Sheet1" trong cửa sổ Project để hiển thị cửa sổ soạn code cho worksheet có tên là Sheet1.

    5. Viết code VBA theo dõi và giám sát việc tương tác của người dùng với worksheet như sau:

    'định nghĩa kiểu miêu tả vị trí cell
    Private Type CellPos
    r As Integer
    c As Integer
    End Type
    'định nghĩa biến chứa các cell bị cấm
    Dim DisableRgn(0 To 100) As CellPos

    'thủ tục theo dõi/giám sátngười dùng
    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim i As Integer
    'xác định các cell bị cấm
    DisableRgn(0).r = 2: DisableRgn(0).c = 3
    DisableRgn(1).r = 3: DisableRgn(1).c = 4
    'phần tử cuối trong danh sách có r = 0
    DisableRgn(2).r = 0: DisableRgn(2).c = 5
    i = 0
    'lặp kiểm tra cell người dùng chọn với các cell bị cấm
    Do While DisableRgn(i).r <> 0
    If DisableRgn(i).c = ActiveCell.Column And DisableRgn(i).r = ActiveCell.Row Then
    'nếu chọn cell cấm thì chọn cell A1
    Range("$A$1").Select
    Exit Do
    End If
    i = i + 1
    Loop
    End Sub

    6. Chọn menu File.Close and Return... để đóng cửa sổ soạn code và quay về cửa sổ wroksheet Excel. Thử chọn vào các cell bị cấm, bạn sẽ thấy máy sẽ dời cursor về ngay cell A1 của worksheet, như vậy người dùng không có cơ hội hiệu chỉnh nội dung các cell bị cấm.

    Lưu ý rằng thay vì tạo file Excel trực tiếp bởi thao tác thủ công như trên, bạn có thể lập trình (bằng bất kỳ ngôn ngữ nào) để tạo tự động file Excel với nội dung các worksheet, nội dung các đoạn code VBA kèm theo từng worksheet theo ý muốn. Đoạn code VBA theo dõi/giám sát thao tác người dùng ở trên sẽ không chạy nếu ứng dụng Excel trên máy khách hàng có mức Security cao.

    Q: Tôi muốn lập trình phần mềm antivirus bằng C# nhưng không biết bắt đầu từ đâu?

    A: Về nguyên tắc, nếu muốn giải quyết vần đề gì, bạn cần phải tìm hiểu và nắm vững vấn đề đó. Áp dụng nguyên tắc này, nếu muốn viết phần mềm diệt virus, trước hết bạn cần tìm hiểu và nắm vững tính chất, nguyên tắc hoạt động, kỹ thuật lây lan cụ thể của các loại virus khác nhau… Có rất nhiều tài liệu giới thiệu những kiến thức phổ thông này, thí dụ Chương 9 của sách "Modern Operating System" của tác giả A. S. Tanenbaumn. Bạn cũng có thể tìm trên Internet nhiều tài liệu về virus, các đoạn code của một số virus cụ thể, các database chứa thông tin nhận dạng nhiều virus phổ biến… Sau khi đã nắm vững mọi điều về virus, bạn có thể bắt đầu viết chương trình tìm và diệt virus, bạn có thể dùng bất kỳ ngôn ngữ lập trình nào, không nhất thiết phải là C#, miễn sao bạn nắm vững và viết thành thạo ngôn ngữ đó.

    Q: Xin hỏi interrupt sử dụng cho thiết bị giao diện bàn phím, cổng COM1, COM2, bộ xung nhịp đồng hồ và đồng hồ thời gian thực?

    A: Bạn có thể tải file ở địa chỉ ftp://ftp.simtel.net/pub/simtelnet/msdos/info/inter60a.zip, bung nó thành 1 thư mục, rồi xem các file đặc tả chi tiết và cụ thể về các interrupt trên máy PC. Thí dụ INT 08 (thường ký hiệu là IRQ0) là ngắt của thiết bị đồng hồ hệ thống, nó xảy ra 18.2 lần /giây.

    ID: A1010_129