문제

VBA(Visual Basic for Application)에서 클래스를 사용하는 것이 적절한 경우는 언제입니까?

나는 추측하고있다 개발 가속화 및 버그 유입 감소 OOP를 지원하는 대부분의 언어에 대한 일반적인 이점입니다.그런데 VBA에는 특별한 기준이 있나요?

도움이 되었습니까?

해결책

이는 누가 코드를 개발하고 유지 관리할 것인지에 따라 다릅니다.소규모 임시 앱을 해킹하는 일반적인 "고급 사용자" 매크로 작성자는 클래스를 사용하면 혼란스러울 수 있습니다.하지만 본격적인 개발을 위해 클래스를 사용하는 이유는 다른 언어와 동일합니다.VB6과 동일한 제한 사항(상속 없음)이 있지만 인터페이스를 사용하면 다형성을 가질 수 있습니다.

클래스를 효과적으로 사용하는 방법은 엔터티와 엔터티 컬렉션을 나타내는 것입니다.예를 들어 Excel 범위를 2차원 배열로 복사한 다음 다음과 같은 코드를 사용하여 2차원 배열을 조작하는 VBA 코드를 자주 봅니다.

Total = 0
For i = 0 To NumRows-1
    Total = Total + (OrderArray(i,1) * OrderArray(i,3))
Next i

다음과 같이 적절하게 이름이 지정된 속성을 사용하여 개체 컬렉션에 범위를 복사하는 것이 더 읽기 쉽습니다.

Total = 0
For Each objOrder in colOrders
    Total = Total + objOrder.Quantity * objOrder.Price
Next i

또 다른 예는 클래스를 사용하여 RAII 디자인 패턴을 구현하는 것입니다(Google에서 검색).예를 들어 워크시트의 보호를 해제하고 몇 가지 조작을 한 다음 다시 보호해야 할 수도 있습니다.클래스를 사용하면 코드에 오류가 발생하더라도 워크시트가 항상 다시 보호됩니다.

--- WorksheetProtector class module ---

Private m_objWorksheet As Worksheet
Private m_sPassword As String

Public Sub Unprotect(Worksheet As Worksheet, Password As String)
    ' Nothing to do if we didn't define a password for the worksheet
    If Len(Password) = 0 Then Exit Sub

    ' If the worksheet is already unprotected, nothing to do
    If Not Worksheet.ProtectContents Then Exit Sub

    ' Unprotect the worksheet
    Worksheet.Unprotect Password

    ' Remember the worksheet and password so we can protect again
    Set m_objWorksheet = Worksheet
    m_sPassword = Password
End Sub

Public Sub Protect()
    ' Protects the worksheet with the same password used to unprotect it
    If m_objWorksheet Is Nothing Then Exit Sub
    If Len(m_sPassword) = 0 Then Exit Sub

    ' If the worksheet is already protected, nothing to do
    If m_objWorksheet.ProtectContents Then Exit Sub

    m_objWorksheet.Protect m_sPassword
    Set m_objWorksheet = Nothing
    m_sPassword = ""
End Sub

Private Sub Class_Terminate()
    ' Reprotect the worksheet when this object goes out of scope
    On Error Resume Next
    Protect
End Sub

그런 다음 이를 사용하여 코드를 단순화할 수 있습니다.

Public Sub DoSomething()
   Dim objWorksheetProtector as WorksheetProtector
   Set objWorksheetProtector = New WorksheetProtector
   objWorksheetProtector.Unprotect myWorksheet, myPassword

   ... manipulate myWorksheet - may raise an error

End Sub 

이 Sub가 종료되면 objWorksheetProtector가 범위를 벗어나고 워크시트가 다시 보호됩니다.

다른 팁

기준은 다른 언어와 같다고 생각합니다

여러 데이터 조각과 일부 메소드를 함께 묶고 객체가 생성/종료될 때 발생하는 일을 구체적으로 처리해야 하는 경우 클래스가 이상적입니다.

예를 들어, 양식을 열 때 실행되는 몇 가지 절차가 있고 그 중 하나에 시간이 오래 걸리는 경우 각 단계의 시간을 측정하기로 결정할 수 있습니다.

시작 및 중지를 위한 명확한 함수에 대한 메서드가 포함된 스톱워치 클래스를 생성할 수 있으며, 그런 다음 시간이 측정되는 프로세스의 이름을 나타내는 인수를 사용하여 지금까지의 시간을 검색하고 이를 텍스트 파일로 보고하는 함수를 추가할 수 있습니다.조사를 위해 가장 느린 성능만 기록하는 논리를 작성할 수 있습니다.

그런 다음 진행률 표시줄 객체를 열고 닫고 현재 작업의 이름을 ms 단위의 시간 및 이전에 저장된 보고서를 기반으로 남은 예상 시간과 함께 표시하는 메서드와 함께 추가할 수 있습니다.

또 다른 예는 Access의 사용자 그룹 쓰레기가 마음에 들지 않으면 로그인 및 로그 아웃 방법과 그룹 수준 사용자 액세스 제어/감사/특정 작업 기록/오류 추적 등을 위한 기능을 사용하여 자신만의 User 클래스를 만들 수 있다는 것입니다.

물론 관련되지 않은 메서드 세트와 많은 변수 전달을 사용하여 이 작업을 수행할 수 있지만 모든 것을 클래스에 캡슐화하는 것이 나에게는 더 나은 것 같습니다.

조만간 VBA의 한계에 가까워지겠지만 이는 매우 강력한 언어이므로 회사에서 VBA에 연결하면 실제로 훌륭하고 복잡한 솔루션을 얻을 수 있습니다.

클래스는 보다 복잡한 API 함수를 처리할 때, 특히 데이터 구조가 필요할 때 매우 유용합니다.

예를 들어 GetOpenFileName() 및 GetSaveFileName() 함수는 많은 멤버가 포함된 OPENFILENAME 구조를 사용합니다.이들 모두를 활용할 필요는 없지만 존재하며 초기화되어야 합니다.

저는 구조(UDT)와 API 함수 선언을 CfileDialog 클래스로 래핑하는 것을 좋아합니다.Class_Initialize 이벤트는 구조 멤버의 기본값을 설정하므로 클래스를 사용할 때 속성 프로시저를 통해 변경하려는 멤버만 설정하면 됩니다.플래그 상수는 Enum으로 구현됩니다.예를 들어 열려는 스프레드시트를 선택하기 위해 내 코드는 다음과 같습니다.

Dim strFileName As String
Dim dlgXLS As New CFileDialog

With dlgXLS
  .Title = "Choose a Spreadsheet"
  .Filter = "Excel (*.xls)|*.xls|All Files (*.*)|*.*"
  .Flags = ofnFileMustExist OR ofnExplorer

  If OpenFileDialog() Then
    strFileName = .FileName
  End If
End With
Set dlgXLS = Nothing

클래스는 기본 디렉터리를 My Documents로 설정하지만 원하는 경우 InitDir 속성을 사용하여 변경할 수 있습니다.

이는 VBA 응용 프로그램에서 클래스가 어떻게 큰 이점을 얻을 수 있는지 보여주는 한 예일 뿐입니다.

특정 기준이 있다고는 말할 수 없지만 VBA 코드에서 클래스를 사용할 수 있는 유용한 위치를 실제로 찾지 못했습니다.내 생각에는 Office 앱 주변의 기존 모델과 너무 연결되어 있어 해당 개체 모델 외부에 추가 추상화를 추가하면 상황이 혼란스러울 뿐입니다.

그 말은 하나도 아니야 할 수 없었다 VBA에서 클래스를 위한 유용한 위치를 찾거나 클래스를 사용하여 완벽하게 유용한 작업을 수행하지만 해당 환경에서는 유용하다고 생각한 적이 없습니다.

실제 클래스를 사용하지 않고도 VBA 코드를 재사용할 수도 있습니다.예를 들어 VBACode라는 호출이 있는 경우입니다.다음 구문을 사용하여 모든 모듈의 모든 함수 또는 하위에 액세스할 수 있습니다.

VBCode.mysub(param1, param2)

템플릿/문서에 대한 참조를 생성하는 경우(dll과 마찬가지로) 동일한 방식으로 다른 프로젝트의 코드를 참조할 수 있습니다.

Microsoft Access를 사용하더라도 객체 지향 프로그래밍을 사용하여 소프트웨어를 개발하는 것은 일반적으로 좋은 방법입니다.이는 여러 가지 장점과 함께 개체를 느슨하게 결합할 수 있도록 하여 향후 확장성을 허용합니다.이는 기본적으로 시스템의 개체가 서로 덜 의존하므로 리팩토링이 훨씬 쉬워진다는 것을 의미합니다.클래스 모듈을 사용하여 이를 달성할 수 있습니다.단점은 VBA에서 클래스 상속이나 다형성을 수행할 수 없다는 것입니다.결국, 클래스 사용에 대한 엄격하고 빠른 규칙은 없으며 단지 모범 사례만 있을 뿐입니다.하지만 애플리케이션이 커질수록 클래스를 사용하여 유지 관리하는 것이 더 쉬워진다는 점을 명심하세요.

데이터 재귀(a.k.a.BOM 처리), 사용자 정의 클래스는 매우 유용하며 때로는 필수 불가결하다고 생각합니다.클래스 모듈 없이도 재귀 함수를 만들 수 있지만 많은 데이터 문제를 효과적으로 해결할 수 없습니다.

(왜 사람들이 VBA용 BOM 라이브러리 세트를 판매하지 않는지 모르겠습니다.어쩌면 XML 도구가 변화를 가져왔을 수도 있습니다.)

다중 양식 인스턴스는 클래스의 일반적인 응용 프로그램입니다(많은 자동화 문제는 그렇지 않으면 해결할 수 없습니다). 질문은 다음과 같습니다. 관습 클래스.

저는 뭔가를 해야 할 때 클래스를 사용하는데, 클래스가 그 일을 가장 잘 해낼 것입니다. 예를 들어, 이벤트에 응답(또는 가로채기)해야 한다면 클래스가 필요합니다.어떤 사람들은 UDT(사용자 정의 유형)를 싫어하지만 나는 UDT를 좋아하므로 일반 영어 자체 문서화 코드를 원할 때 UDT를 사용합니다.Pharmacy.NCPDP는 strPhrmNum보다 훨씬 읽기 쉽습니다 :) 그러나 UDT는 제한되어 있으므로 Pharmacy.NCPDP를 설정하고 다른 모든 속성을 채우고 싶다고 가정해 보겠습니다.그리고 실수로 데이터를 변경할 수 없도록 만들고 싶습니다.그런 다음 UDT 등에 읽기 전용 속성이 없기 때문에 클래스가 필요합니다.

또 다른 고려 사항은 단순한 가독성입니다.복잡한 데이터 구조를 수행하는 경우 Company.Owner.Phone.AreaCode를 호출한 다음 모든 것이 구조화된 위치를 추적하면 된다는 점을 아는 것이 도움이 되는 경우가 많습니다.특히 퇴사 후 2년 동안 해당 코드베이스를 유지해야 하는 사람들에게는 더욱 그렇습니다. :)

내 자신의 두 센트는 "목적이 있는 코드"입니다.이유 없이 수업을 사용하지 마세요.하지만 이유가 있다면 그렇게 하세요 :)

다양한 클라이언트를 위해 제공되는 많은 VBA 프로젝트에서 사용할 자체 캡슐화된 코드 패키지를 만들려면 클래스를 사용합니다.

레코드 세트 및 쿼리 정의보다 더 편리한 액세스 시 SQL 래퍼 클래스를 정의할 수 있습니다.예를 들어 다른 관련 테이블의 기준에 따라 테이블을 업데이트하려는 경우 조인을 사용할 수 없습니다.이를 위해 vba recorset 및 querydef를 구축할 수 있지만 클래스를 사용하면 더 쉽습니다.또한 애플리케이션에 2개 이상의 테이블이 필요한 개념이 있을 수 있으므로 이를 위해 클래스를 사용하는 것이 더 나을 수도 있습니다.예:응용 프로그램은 사건을 추적합니다.사건에는 여러 테이블(사용자 및 해당 연락처 또는 프로필, 사건 설명;상태 추적;지원 담당자가 사건에 대응하는 데 도움이 되는 체크리스트회신하다 ...} .관련된 모든 쿼리와 관계를 추적하려면 oop가 도움이 될 수 있습니다.코딩을 다 하는 대신 Incident.Update(xxx)를 할 수 있어서 다행이다...

특히 VB.NET을 참조하는 경우 VBA에 대한 기준이 다른 언어와 다른 이유가 무엇인지 알 수 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top