2013-07-15 6 views
2

VBA를 사용하여 Excel 2010에서 만든 사용자 정의 폼이 있습니다. 컨트롤은 특정 시트의 데이터를 기반으로 프로그래밍 방식으로 폼에 추가됩니다. 내 코드는 모든 컨트롤을 추가 한 다음 폼이 지나치게 긴지 여부를 결정합니다. 그럴 경우 양식이 최대 높이 500px로 설정되고 스크롤링이 사용됩니다.Excel 2010 UserForm - 양식이 마우스 휠로 스크롤되지 않습니다.

스크롤 막대를 클릭 할 때 스크롤 막대가 예상대로 작동하지만 마우스 스크롤 휠은 양식의 스크롤 막대에는 영향을주지 않습니다.

마우스 휠 스크롤을 사용하기위한 속성을 보지 못했습니다. Google에서 발견 한 모든 기사는 사용자 정의 폼 (ListBox, ComboBox 등) 내에서 스크롤하는 컨트롤을 가리키며 사용자 정의 폼 자체는 가리 킵니다. 내가 찾은 다른 기사는 마우스 휠 스크롤링을 지원하지 않는 Excel 2003의 것으로 거슬러 올라갑니다.

여기에 무슨 일이 일어나는 지 아는 사람이 있습니까?

If Me.height > 500 Then 
    Me.ScrollHeight = Me.height 
    Me.ScrollBars = fmScrollBarsVertical 
    Me.KeepScrollBarsVisible = fmScrollBarsVertical 
    Me.height = 500 
    Me.Width = Me.Width + 12 
End If 

내가 엑셀 ​​2010 (32 비트)를 사용하고 윈도우 7 64 비트 노트북 : 여기

내가 스크롤 가능하게하는 코드입니다. 같은 문제가 다른 컴퓨터에도 나타나고 같은 설정이 실행됩니다. 다른 구성에 액세스 할 필요가 없습니다.

+0

[이 SO Q & A] (http://stackoverflow.com/)를 확인하십시오. 질문/15992475/excel-vba-how-to-enable-mouse-wheel-scroll-in-combobox-listbox) –

+1

@KazJaw - 나는 그 질문을 보았다. 나는 UserForm 자체와 관련이 없으며 대신 OP가 폼 내에서 컨트롤을 스크롤하려고합니다. 저는 VBA를 처음 사용 합니다만, 닷넷과 다른 언어로 컨트롤을 스크롤하는 것과 폼을 스크롤하는 것이 매우 다른 것들이 있습니다. – Brian

답변

2

32 비트 Excel에서만 작동하도록 설정할 수 있습니다. 코드는 64 비트 Excel에서 전혀 컴파일 및 실행되지 않습니다. 32 비트와 64 비트 모두와 호환되는 (조금 더 복잡한) 버전을 만들었지 만 64 비트에서는 스크롤하지 않고 적어도 컴파일 만하면됩니다 (누군가가 64 비트 버전을 필요로하는지 알려주세요) bit 호환 코드). (mouseOverFrame_를

Option Explicit 
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _ 
    (ByVal lpClassName As String, ByVal lpWindowName As String) As Long 
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _ 
     (ByVal hwnd As Long, ByVal nIndex As Long) As Long 
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _ 
     (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long 
Private Const GWL_STYLE As Long = (-16)   'The offset of a window's style 
Private Const WS_SYSMENU As Long = &H80000  'Style to add a system menu 
Private Const WS_MINIMIZEBOX As Long = &H20000 'Style to add a Minimize box on the title bar 
Private Const WS_MAXIMIZEBOX As Long = &H10000 'Style to add a Maximize box to the title bar 
'To be able to scroll with mouse wheel within Userform 
Private Declare Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcA" (_ 
    ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, _ 
    ByVal lParam As Long) As Long 

Private Const GWL_WNDPROC = -4 
Private Const WM_MOUSEWHEEL = &H20A 
Dim LocalHwnd As Long 
Dim LocalPrevWndProc As Long 
Dim myForm As UserForm 
Private Function WindowProc(ByVal Lwnd As Long, ByVal Lmsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long 
'To handle mouse events 
Dim MouseKeys As Long 
Dim Rotation As Long 
If Lmsg = WM_MOUSEWHEEL Then 
    MouseKeys = wParam And 65535 
    Rotation = wParam/65536 
    'My Form s MouseWheel function 
'================================================================= 
    YOUR_USERFORM_NAME_HERE.MouseWheel Rotation 
'================================================================= 
End If 
WindowProc = CallWindowProc(LocalPrevWndProc, Lwnd, Lmsg, wParam, lParam) 
End Function 
Public Sub WheelHook(PassedForm As UserForm) 
'To get mouse events in userform 
On Error Resume Next 
Set myForm = PassedForm 
LocalHwnd = FindWindow("ThunderDFrame", myForm.Caption) 
LocalPrevWndProc = SetWindowLong(LocalHwnd, GWL_WNDPROC, AddressOf WindowProc) 
End Sub 
Public Sub WheelUnHook() 
'To Release Mouse events handling 
Dim WorkFlag As Long 
On Error Resume Next 
WorkFlag = SetWindowLong(LocalHwnd, GWL_WNDPROC, LocalPrevWndProc) 
Set myForm = Nothing 
End Sub 

을 그리고 당신은 "frames_을 대체하는 것을 잊지 마세요 ... (사용자 정의 폼에 간단한 코드를 추가

그래서, 당신은 새 모듈을 만들고 WinAPI를 호출 거기에 코드를 붙여 넣습니다) ")를 스크롤하려는 UI 컨트롤의 이름으로 바꿉니다. 나는 세 가지 프레임을 스크롤하고 싶었 기 때문에

Public Sub MouseWheel(ByVal Rotation As Long) 
'************************************************ 
' To respond from MouseWheel event 
' Scroll accordingly to direction 
' 
' Made by: Mathieu Plante 
' Date:  July 2004 
'************************************************ 
Select Case frames_(mouseOverFrame_).ScrollTop - Sgn(Rotation) * 18 
Case Is < 0 
frames_(mouseOverFrame_).ScrollTop = 0 
Case Is > frames_(mouseOverFrame_).ScrollHeight 
frames_(mouseOverFrame_).ScrollTop = frames_(mouseOverFrame_).ScrollHeight 
Case Else 
frames_(mouseOverFrame_).ScrollTop = frames_(mouseOverFrame_).ScrollTop - Sgn(Rotation) * 18 
End Select 
End Sub 

(프레임은 마우스 커서 아래에 현재에 따라) - I 프레임 번호 "를 할당하는 각 프레임에 세 개의 프레임 사용"MouseMove 이벤트 "이벤트의 컬렉션을 만든 mouseOverFrame_ "변수. 예를 들어 마우스가 움직일 때 첫 번째 프레임에서 스크롤러는 "mouseOverFrame_"변수 안에 "1"을 포함하여 스크롤 할 프레임을 알 수 있습니다 ...

관련 문제