2009-07-01 23 views
29

Các tính năng nào của ngôn ngữ VBA hoặc là được ghi chép kém hoặc đơn giản là không thường xuyên sử dụng?Các tính năng ẩn của VBA

+0

@bbqchickenrobot Tôi thực sự không có nhiều lựa chọn. Với liều lượng nhỏ nó không phải là xấu, anyway. – guillermooo

Trả lời

7

tính năng Hidden

  1. Mặc dù nó là "cơ bản", bạn có thể sử dụng OOP - lớp và các đối tượng
  2. Bạn có thể làm cho API gọi
+5

Đối với bất kỳ ai nói rằng OO trong VBA không phải là OO, hãy vượt qua nó. Giao tiếp kế thừa cũng là thừa kế - nó chỉ là một loại khác. –

+0

Tôi yêu hỗ trợ (mặc dù có giới hạn) đối với OO trong VBA. Đặc biệt là khả năng thực hiện nhiều giao diện. –

+0

Hai tính năng này hầu như không bị ẩn, phải không? –

3

Hỗ trợ cho các phiên bản địa phương, trong đó (ít nhất trong thế kỷ trước) hỗ trợ các biểu thức bằng cách sử dụng các giá trị được bản địa hóa. Giống như Pravda cho True và Fałszywy (không quá chắc chắn, nhưng ít nhất nó đã có L vui) cho False trong tiếng Ba Lan ... Trên thực tế phiên bản tiếng Anh sẽ có thể đọc macro bằng bất kỳ ngôn ngữ nào, và chuyển đổi khi đang bay. Các phiên bản được bản địa hóa khác sẽ không xử lý điều đó.

FAIL.

6

Bạn có thể triển khai giao diện bằng từ khóa Implements.

13

Nó không phải là một tính năng, nhưng một điều tôi đã thấy sai rất nhiều lần trong VBA (và VB6): ngoặc thêm về phương pháp gọi nơi mà nó sẽ thay đổi ngữ nghĩa:

Sub Foo() 

    Dim str As String 

    str = "Hello" 

    Bar (str) 
    Debug.Print str 'prints "Hello" because str is evaluated and a copy is passed 

    Bar str 'or Call Bar(str) 
    Debug.Print str 'prints "Hello World" 

End Sub 

Sub Bar(ByRef param As String) 

    param = param + " World" 

End Sub 
+2

+1 Tôi chưa tìm thấy một ví dụ duy nhất mà từ khóa cuộc gọi thực sự cần thiết. 'Gọi foo (bar)' luôn có thể được thay thế bằng 'foo bar' để cuộc gọi có vẻ dư thừa. Đi theo các câu hỏi của VBA trên SO, nhiều người dường như không biết rằng dấu ngoặc đơn không cần gọi một Sub để chúng ta có thể gọi đây là một tính năng kém được hiểu là – barrowc

+0

Nếu Bar là một hàm và bạn sử dụng 'Bar (str)' thay vì 'Bar (str) 'dấu ngoặc đơn không ghi đè từ khóa ByRef. – Kuyenda

+0

@Kuyenda: Không gian được chèn tự động bởi VBA-IDE khi mã được biên dịch. Bạn đã chạy phiên bản 'Bar (str)' như thế nào? –

4

Với một công việc ít, bạn có thể duyệt qua các bộ sưu tập tùy chỉnh như thế này:

' Write some text in Word first.' 
Sub test() 
    Dim c As New clsMyCollection 
     c.AddItems ActiveDocument.Characters(1), _ 
      ActiveDocument.Characters(2), _ 
      ActiveDocument.Characters(3), _ 
      ActiveDocument.Characters(4) 

    Dim el As Range 
    For Each el In c 
     Debug.Print el.Text 
    Next 
    Set c = Nothing 
End Sub 

bạn đang sưu tập tùy chỉnh (trong một lớp được gọi là clsMyCollection):

Option Explicit 

Dim m_myCollection As Collection 

Public Property Get NewEnum() As IUnknown 
    ' This property allows you to enumerate 
    ' this collection with the For...Each syntax 
    ' Put the following line in the exported module 
    ' file (.cls)!' 
    'Attribute NewEnum.VB_UserMemId = -4 
    Set NewEnum = m_myCollection.[_NewEnum] 
End Property 

Public Sub AddItems(ParamArray items() As Variant) 

    Dim i As Variant 

    On Error Resume Next 
    For Each i In items 
     m_myCollection.Add i 
    Next 
    On Error GoTo 0 
End Sub 

Private Sub Class_Initialize() 
    Set m_myCollection = New Collection 
End Sub 
15

Bản thân VBA có vẻ là một tính năng ẩn. Folks Tôi biết những người đã sử dụng sản phẩm văn phòng trong nhiều năm không có ý tưởng nó thậm chí là một phần của bộ.

Tôi đã đăng câu hỏi này lên nhiều câu hỏi tại đây, nhưng Object Browser là vũ khí bí mật của tôi. Nếu tôi cần phải mã ninja một cái gì đó thực sự nhanh chóng, nhưng không quen thuộc với dll của, Object Browser tiết kiệm cuộc sống của tôi. Nó làm cho nó dễ dàng hơn nhiều để tìm hiểu các cấu trúc lớp hơn MSDN.

Cửa sổ cục bộ cũng tuyệt vời để gỡ lỗi. Đặt một tạm dừng trong mã của bạn và nó sẽ cho bạn thấy tất cả các biến, tên của họ, và các giá trị hiện tại của họ và các loại trong không gian tên hiện tại.

Và ai có thể quên người bạn tốt của chúng tôi Cửa sổ ngay lập tức? Nó không chỉ tuyệt vời cho đầu ra tiêu chuẩn Debug.Print, nhưng bạn cũng có thể nhập các lệnh vào nó. Cần biết VariableX là gì?

?VariableX 

Cần biết màu ô đó là gì?

?Application.ActiveCell.Interior.Color 

Thực tế tất cả các cửa sổ này là công cụ tuyệt vời để làm việc hiệu quả với VBA.

+1

"Những người tôi biết đã sử dụng sản phẩm Office trong nhiều năm không có ý tưởng nó thậm chí là một phần của bộ." - đó là những gì giữ một phần công việc kinh doanh của tôi còn sống, thực tế là tôi được kêu gọi thực hiện loại công việc này. Nếu họ học được cách để làm điều đó (và/hoặc giỏi về nó) - tôi sẽ không đi làm. :-) – Taptronic

+0

Tôi cũng vậy. Tôi cảm thấy VBA sẽ biến thành COBOL của năm qua. Các ứng dụng VBA sẽ có mặt tại đây và cần được cập nhật nhưng mọi người sẽ chuyển sang ngôn ngữ quyến rũ hơn. – mandroid

+0

Cấu trúc lớp trên MSDN? Trước tiên, bạn phải goto "MyClass" để có được một cái nhìn tổng quan vô ích và ít khi sử dụng các ví dụ, sau đó "MyClass phương pháp" để có được một danh sách các phương pháp sau đó "MyClass Properties" để tìm các tài sản ... sau đó cho hiearchy .... bạn biết MSDN thường là phương sách cuối cùng của tôi. – Earlz

2

Mô hình đối tượng VBE (Visual Basic Extensibility) là một tính năng ít được biết đến và/hoặc ít được sử dụng hơn. Nó cho phép bạn viết mã VBA để thao tác mã VBA, các mô đun và các dự án. Tôi đã từng viết một dự án Excel có thể tập hợp các dự án Excel khác từ một nhóm các tệp mô-đun.

Mô hình đối tượng cũng hoạt động từ VBScript và HTA. Tôi đã viết một HTA cùng một lúc để giúp tôi theo dõi một số lượng lớn các dự án Word, Excel và Access.Nhiều dự án sẽ sử dụng các mô-đun mã phổ biến và dễ dàng cho các mô-đun "phát triển" trong một hệ thống và sau đó cần được di chuyển sang các hệ thống khác. HTA của tôi sẽ cho phép tôi xuất tất cả các mô-đun trong một dự án, so sánh chúng với các phiên bản trong một thư mục chung và kết hợp các thường trình được cập nhật (sử dụng BeyondCompare), sau đó nhập lại các mô-đun cập nhật.

Mô hình đối tượng VBE hoạt động hơi khác nhau giữa Word, Excel và Access và tiếc là không hoạt động với Outlook, nhưng vẫn cung cấp khả năng quản lý mã tuyệt vời.

18

Có một tính năng quan trọng nhưng hầu như luôn bị bỏ lỡ của câu lệnh Giữa(). Đó là nơi Mid() xuất hiện ở phía bên tay trái của một nhiệm vụ trái ngược với hàm Mid() xuất hiện ở phía bên tay phải hoặc trong một biểu thức.

Quy tắc là nếu chuỗi đích không phải là chuỗi ký tự, và đây là tham chiếu duy nhất cho chuỗi đích và độ dài của đoạn được chèn khớp với độ dài của đoạn được thay thế, thì chuỗi sẽ được coi là có thể thay đổi cho hoạt động.

Điều đó có nghĩa là gì? Nó có nghĩa là nếu bạn xây dựng một báo cáo lớn hoặc một danh sách lớn các chuỗi thành một chuỗi giá trị duy nhất, sau đó khai thác điều này sẽ làm cho chuỗi của bạn xử lý nhanh hơn nhiều.

Đây là một lớp học đơn giản có lợi từ việc này. Nó cung cấp cho VBA của bạn cùng khả năng StringBuilder mà .Net có.

' Class: StringBuilder 

Option Explicit 

Private Const initialLength As Long = 32 

Private totalLength As Long ' Length of the buffer 
Private curLength As Long ' Length of the string value within the buffer 
Private buffer As String  ' The buffer 

Private Sub Class_Initialize() 
    ' We set the buffer up to it's initial size and the string value "" 
    totalLength = initialLength 
    buffer = Space(totalLength) 
    curLength = 0 
End Sub 

Public Sub Append(Text As String) 

    Dim incLen As Long ' The length that the value will be increased by 
    Dim newLen As Long ' The length of the value after being appended 
    incLen = Len(Text) 
    newLen = curLength + incLen 

    ' Will the new value fit in the remaining free space within the current buffer 
    If newLen <= totalLength Then 
    ' Buffer has room so just insert the new value 
    Mid(buffer, curLength + 1, incLen) = Text 
    Else 
    ' Buffer does not have enough room so 
    ' first calculate the new buffer size by doubling until its big enough 
    ' then build the new buffer 
    While totalLength < newLen 
     totalLength = totalLength + totalLength 
    Wend 
    buffer = Left(buffer, curLength) & Text & Space(totalLength - newLen) 
    End If 
    curLength = newLen 
End Sub 

Public Property Get Length() As Integer 
    Length = curLength 
End Property 

Public Property Get Text() As String 
    Text = Left(buffer, curLength) 
End Property 

Public Sub Clear() 
    totalLength = initialLength 
    buffer = Space(totalLength) 
    curLength = 0 
End Sub 

Và đây là một ví dụ về cách sử dụng nó:

Dim i As Long 
    Dim sb As StringBuilder 
    Dim result As String 
    Set sb = New StringBuilder 
    For i = 1 to 100000 
    sb.Append CStr(i) 
    Next i 
    result = sb.Text 
+0

tuyệt vời, mã tốt đẹp –

7

Có thể các tính năng ghi nhận ít nhất là trong VBA là những bạn chỉ có thể vạch trần bằng cách chọn "Show Hidden viên" trên Object Browser VBA . Thành viên ẩn là những chức năng có trong VBA, nhưng không được hỗ trợ. Bạn có thể sử dụng chúng, nhưng microsoft có thể loại bỏ chúng bất cứ lúc nào. Không ai trong số họ có bất kỳ tài liệu nào được cung cấp, nhưng bạn có thể tìm thấy một số tài liệu trên web. Có thể nói nhiều nhất về các tính năng ẩn này cung cấp truy cập tới các con trỏ trong VBA. Đối với một ghi phong nha, hãy kiểm tra; Not So Lightweight - Shlwapi.dll

Tài liệu, nhưng có lẽ ít mơ hồ hơn (trong excel anyways) đang sử dụng ExecuteExcel4Macro để truy cập vào không gian tên toàn cục bị ẩn thuộc về toàn bộ ứng dụng Excel như trái ngược với sổ làm việc cụ thể.

+0

+1 cho ExecuteExcel4Macro lừa, tôi đã tự hỏi làm thế nào bạn đã làm điều đó từ mã. –

32

Thủ thuật này chỉ hoạt động trong Access VBA, Excel và các công cụ khác sẽ không cho phép. Nhưng bạn có thể tạo một Mô-đun Chuẩn bị ẩn khỏi trình duyệt đối tượng bằng cách đặt trước tên Mô-đun bằng dấu gạch dưới. Sau đó, mô-đun sẽ chỉ hiển thị nếu bạn thay đổi trình duyệt đối tượng để hiển thị các đối tượng ẩn.

Thủ thuật này hoạt động với Enums trong tất cả phiên bản Vb6 dựa trên VBA. Bạn có thể tạo một thành viên ẩn của một Enum bằng cách đặt tên của nó trong dấu ngoặc vuông, sau đó đặt tên nó là dấu gạch dưới.Ví dụ:

Public Enum MyEnum 
    meDefault = 0 
    meThing1 = 1 
    meThing2 = 2 
    meThing3 = 3 
    [_Min] = meDefault 
    [_Max] = meThing3 
End Enum 

Public Function IsValidOption(ByVal myOption As MyEnum) As Boolean 
    If myOption >= MyEnum.[_Min] Then IsValidOption myOption <= MyEnum.[_Max] 
End Function 

Trong Excel-VBA bạn có thể tham khảo các tế bào bằng cách bao chúng trong dấu ngoặc, các dấu ngoặc cũng có chức năng như một evaluate command cho phép bạn đánh giá cú pháp công thức:

Public Sub Example() 
    [A1] = "Foo" 
    MsgBox [VLOOKUP(A1,A1,1,0)] 
End Sub 

Ngoài ra bạn có thể vượt qua xung quanh liệu dữ liệu mà không sử dụng MemCopy (RtlMoveMemory) bằng cách kết hợp với LSet User Defined loại của cùng một kích thước:

Public Sub Example() 
    Dim b() As Byte 
    b = LongToByteArray(8675309) 
    MsgBox b(1) 
End Sub 

Private Function LongToByteArray(ByVal value As Long) As Byte() 
    Dim tl As TypedLong 
    Dim bl As ByteLong 
    tl.value = value 
    LSet bl = tl 
    LongToByteArray = bl.value 
End Function 

Octal & Hex Literals thực sự là loại unsigned, những sẽ cả sản lượng -32.768:

Public Sub Example() 
    Debug.Print &H8000 
    Debug.Print &O100000 
End Sub 

Như đã đề cập, đi qua một biến bên trong ngoặc làm cho nó được thông qua ByVal:

Sub PredictTheOutput() 
    Dim i&, j&, k& 
    i = 10: j = i: k = i 
    MySub (i) 
    MySub j 
    MySub k + 20 
    MsgBox Join(Array(i, j, k), vbNewLine), vbQuestion, "Did You Get It Right?" 
End Sub 

Public Sub MySub(ByRef foo As Long) 
    foo = 5 
End Sub 

Bạn có thể gán một chuỗi trực tiếp vào mảng byte và ngược lại:

Public Sub Example() 
    Dim myString As String 
    Dim myBytArr() As Byte 
    myBytArr = "I am a string." 
    myString = myBytArr 
    MsgBox myString 
End Sub 

"Giữa" cũng là toán tử. Sử dụng nó, bạn ghi đè lên các phần cụ thể của các chuỗi mà không cần ghép nối chuỗi khét tiếng của VBA:

Public Sub Example1() 
    ''// This takes about 47% of time Example2 does: 
    Dim myString As String 
    myString = "I liek pie." 
    Mid(myString, 5, 2) = "ke" 
    Mid(myString, 11, 1) = "!" 
    MsgBox myString 
End Sub 

Public Sub Example2() 
    Dim myString As String 
    myString = "I liek pie." 
    myString = "I li" & "ke" & " pie" & "!" 
    MsgBox myString 
End Sub 
+6

Câu trả lời này đảm bảo cách nhận biết nhiều hơn nhận được ... – nathanchere

6

Từ điển. VBA là thực tế vô giá trị mà không có họ!

Tham khảo Thời gian chạy Microsoft Scripting, sử dụng Scripting.Dictionary cho mọi tác vụ đầy đủ phức tạp và sống hạnh phúc mãi mãi.

Thời gian chạy tập lệnh cũng cung cấp cho bạn FileSystemObject, cũng được đề xuất.

Bắt đầu ở đây, sau đó đào xung quanh một chút ...

http://msdn.microsoft.com/en-us/library/aa164509%28office.10%29.aspx

1

VBA hỗ trợ các nhà khai thác Bitwise để so sánh các chữ số nhị phân (bit) trong hai giá trị. Ví dụ, biểu thức 4 và 7 đánh giá các giá trị bit của 4 (0100) và 7 (0111) và trả về 4 (bit nằm trên cả hai số.) Tương tự như biểu thức 4 hoặc 8 đánh giá các giá trị bit trong 4 (0100) và 8 (1000) và trả về 12 (1100), tức là các bit trong đó một trong hai giá trị là đúng.

Thật không may, các toán tử bitwise có cùng tên tại các toán tử so sánh logic: Và, Eqv, Imp, Not, Or và Xor. Điều này có thể dẫn đến sự mơ hồ, và thậm chí kết quả mâu thuẫn.

Ví dụ: mở Cửa sổ ngay lập tức (Ctrl + G) và nhập: ? (2 và 4) Điều này trả về không, vì không có bit chung giữa 2 (0010) và 4 (0100).

4
  • Lưu 4 lần nhấn phím bằng cách nhập debug.? xxx thay vì debug.print xxx.
  • Sụp đổ bằng cách thêm: enum foo: me=0: end enum lên đầu mô-đun có chứa bất kỳ mã nào khác.
5

Nhập VBA. sẽ hiển thị danh sách đầy đủ tất cả các hàm và hằng số được tích hợp sẵn.

2

IsDate("13.50") lợi nhuận True nhưng IsDate("12.25.2010") lợi nhuận False

Điều này là do IsDate có thể được đặt tên chính xác hơn IsDateTime. Và vì khoảng thời gian (.) được coi là dấu phân cách thời gian chứ không phải dấu phân cách ngày. Xem here for a full explanation.

0

Deftype Statements

Tính năng này tồn tại có lẽ cho tương thích ngược. Hoặc để viết mã spaghetti vô vọng làm xáo trộn. Lựa chọn của bạn.

+0

Bây giờ, đừng quá khắc nghiệt với VBA. Đây là công cụ tương thích ngược. Ngày xửa ngày xưa, các byte quan trọng. (Đây là tổ tiên VBA sớm nhất với các câu lệnh DEFxxx mà tôi có thể tìm thấy trong 60 giây của Googling: http://en.wikipedia.org/wiki/GW-BASIC) – jtolle

+0

Đủ công bằng. Tôi sẽ cập nhật câu trả lời của tôi cho phù hợp. – mwolfe02

+0

Dường như IBM BASICA và các phiên bản trước đó của nó cũng hỗ trợ nó. Xem p.4-73 trong http://www.retroarchive.org/dos/docs/basic_ref_1.pdf. Ngoài ra kiểm tra p.4-68; Tôi ước gì tôi biết về 'DEF FN' hồi đó. Thời gian tốt... – jtolle

Các vấn đề liên quan