Giúp sửa code trong Form để quản lý sheet (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

vc_đi chơi

Thành viên thường trực
Tham gia
21/9/19
Bài viết
201
Được thích
41
Em có tham khảo và làm giao diện Form để quản lý sheet, nhưng em không hiểu sao bị lỗi khi tìm kiếm tên sheet không được hiển thị lên.
Nhờ các anh chị giúp em hoàn thiện đoạn code và chỉnh giúp em giao diện Form để khi quản lý sheet thì có giao diện (như hình em đăng )
Em có tải file em làm rồi nhưng bị lỗi.
Em xin cảm ơn!
Đoạn code như sau:

Mã:
Private Sub txtTenHH_Change()
    If txtTenHH <> "" Then
        cmdShowSheet_Click
        For k = ListBox1.ListCount - 1 To 0 Step -1
            If Not UCase(ListBox1.List(k)) Like "*" & UCase(txtTenHH) & "*" Then
                ListBox1.RemoveItem (k)
            End If
        Next
    ElseIf txtTenHH = "" Then
        cmdShowSheet_Click
    End If
End Sub

'---Code cho ListBox(lstSheets)
Private Sub lstSheets_Click()
    Sheets(frmShowSheet.lstSheets.Value).Select
    frmShowSheet.txtTenHH.SetFocus
End Sub

'---Code cho CommandButton(cmdShowSheet)
Private Sub cmdShowSheet_Click()
    Dim Sh As Worksheet
    For Each Sh In Sheets
        frmShowSheet.lstSheets.AddItem Sh.Name
    Next
    Dim i As Long, j As Long
    With lstSheets
        For i = 0 To .ListCount - 1
            For j = .ListCount - 1 To (i + 1) Step -1
                If .List(j) = .List(i) Then
                    .RemoveItem j
                    frmShowSheet.txtTenHH.SetFocus
                End If
            Next j
        Next i
    End With
End Sub

111111.png
 

File đính kèm

Em có tham khảo và làm giao diện Form để quản lý sheet, nhưng em không hiểu sao bị lỗi khi tìm kiếm tên sheet không được hiển thị lên.
Nhờ các anh chị giúp em hoàn thiện đoạn code và chỉnh giúp em giao diện Form để khi quản lý sheet thì có giao diện (như hình em đăng )
Em có tải file em làm rồi nhưng bị lỗi.
Em xin cảm ơn!
Đoạn code như sau:

Mã:
Private Sub txtTenHH_Change()
    If txtTenHH <> "" Then
        cmdShowSheet_Click
        For k = ListBox1.ListCount - 1 To 0 Step -1
            If Not UCase(ListBox1.List(k)) Like "*" & UCase(txtTenHH) & "*" Then
                ListBox1.RemoveItem (k)
            End If
        Next
    ElseIf txtTenHH = "" Then
        cmdShowSheet_Click
    End If
End Sub

'---Code cho ListBox(lstSheets)
Private Sub lstSheets_Click()
    Sheets(frmShowSheet.lstSheets.Value).Select
    frmShowSheet.txtTenHH.SetFocus
End Sub

'---Code cho CommandButton(cmdShowSheet)
Private Sub cmdShowSheet_Click()
    Dim Sh As Worksheet
    For Each Sh In Sheets
        frmShowSheet.lstSheets.AddItem Sh.Name
    Next
    Dim i As Long, j As Long
    With lstSheets
        For i = 0 To .ListCount - 1
            For j = .ListCount - 1 To (i + 1) Step -1
                If .List(j) = .List(i) Then
                    .RemoveItem j
                    frmShowSheet.txtTenHH.SetFocus
                End If
            Next j
        Next i
    End With
End Sub

View attachment 229501
Thử cách này.
 

File đính kèm

Cám ơn anh! anh ơi phiền anh chút xíu nữa:
1/ Anh cho em hỏi có cách nào để bảng Form trên hiện theo vị trí của chuột (chuột ở ô excel nào đó thì chạy code sẽ hiện lên bảng Form ở vị trí khoảng ô quanh đó, ở đây em thấy nó luôn hiện ra ở giữa màn hình) " Em muốn hiện lên ở vị trí con trỏ chuột_Như hình thứ 2 và thứ 3"
2/ Anh sửa giúp em giao diện ddeerr nó có nền và chữ nổi lên một chút cho dễ nhìn như sau được không ạ? _Như hình thứ nhất.

2222.png333333.png

111111.png
 
Lần chỉnh sửa cuối:
Cám ơn anh! anh ơi phiền anh chút xíu nữa:
1/ Anh cho em hỏi có cách nào để bảng Form trên hiện theo vị trí của chuột (chuột ở ô excel nào đó thì chạy code sẽ hiện lên bảng Form ở vị trí khoảng ô quanh đó, ở đây em thấy nó luôn hiện ra ở giữa màn hình) " Em muốn hiện lên ở vị trí con trỏ chuột_Như hình thứ 2 và thứ 3"
2/ Anh sửa giúp em giao diện ddeerr nó có nền và chữ nổi lên một chút cho dễ nhìn như sau được không ạ? _Như hình thứ nhất.

View attachment 229512View attachment 229513

View attachment 229510
Hay đấy! gọn nhẹ và tiện dụng, rất cần.
Cảm ơn vc_đi chơi giaiphap.
Mong giaiphap giúp đỡ và cho ý tưởng để giao diện đẹo hơn và có hướng nào đó hay ơn!
Biết ơn các bạn!
 
Em ẩn sheet1 đi khi chạy code thì vẫn hiện tên sheet1 lên và khi nhấn vào đó sẽ báo lỗi.
Anh có thể sửa code để những sheet đã ẩn không hiện lên khi chạy code.
Hoặc tích hợp tính năng ẩn/hiện sheet vào luôn Form này.
loi.png
 
Hi mọi người,
Em cũng có mò trên mạng 1 form để unhide and hide sheet. E đã tạo form nhưng vấn đề ở đây là e muốn khi hiện form mà vẫn có thể làm việc đồng thời trên bảng tính excel . Nhưng code của e chỉ khi close mới unhide or hide sheet được. Và form thì luôn luôn hiện ở giữa ..Có cách nào để em có thể di chuyển tùy ý form được không ạ.
Em cảm ơn.
 

File đính kèm

Hi mọi người,
Em cũng có mò trên mạng 1 form để unhide and hide sheet. E đã tạo form nhưng vấn đề ở đây là e muốn khi hiện form mà vẫn có thể làm việc đồng thời trên bảng tính excel . Nhưng code của e chỉ khi close mới unhide or hide sheet được. Và form thì luôn luôn hiện ở giữa ..Có cách nào để em có thể di chuyển tùy ý form được không ạ.
Em cảm ơn.
Muốn hiện Form mà vẫn thực hiện trên bảng tình thì để thuộc tính ShowModal của Form về False nhé.
 
Hi mọi người,
Em cũng có mò trên mạng 1 form để unhide and hide sheet. E đã tạo form nhưng vấn đề ở đây là e muốn khi hiện form mà vẫn có thể làm việc đồng thời trên bảng tính excel . Nhưng code của e chỉ khi close mới unhide or hide sheet được. Và form thì luôn luôn hiện ở giữa ..Có cách nào để em có thể di chuyển tùy ý form được không ạ.
Em cảm ơn.
Cái của mình và cái của bạn gộp làm 1 thì hay đấy.
Có ý tưởng sau:
qqqqqq.png
Của bạn cần click đúp để chọn sheet để ẩn hoặc chọn sheet hiện
Chỉnh lại là chỉ cần clik (một lần) thì sẽ chọn sheet để ẩn hoặc chọn sheet hiện.
Còn Click 2 lần vào tên của "Danh sách sheet Hiện" sẽ đến được sheet đã hiện đó.
Nhờ các bác trên GPE giúp đỡ!
 

File đính kèm

1/ Anh cho em hỏi có cách nào để bảng Form trên hiện theo vị trí của chuột (chuột ở ô excel nào đó thì chạy code sẽ hiện lên bảng Form ở vị trí khoảng ô quanh đó, ở đây em thấy nó luôn hiện ra ở giữa màn hình) " Em muốn hiện lên ở vị trí con trỏ chuột_Như hình thứ 2 và thứ 3"
View attachment 229513
Thế nếu trong hình 3 mà P24 đang được chọn thì hiện Form thế nào? Hiện sao cho chỉ nhìn thấy một góc trên bên trái nhỏ của Form, không nhìn thấy TextBox và ListBox?

form.JPG
 
Thế nếu trong hình 3 mà P24 đang được chọn thì hiện Form thế nào? Hiện sao cho chỉ nhìn thấy một góc trên bên trái nhỏ của Form, không nhìn thấy TextBox và ListBox?

View attachment 229547
Hì, Em dùng từ "quanh quanh" khu đó thôi anh ạ!
Em có ý tưởng vậy, anh có hướng giải quyết thế nào chó em xin ý kiến mới để em học hỏi.
Em có tải file ở bài #9 khi kết hợp ý tưởng ở bài #7 của Thanh Bình PV.
Anh giúp em mới nhé!
Cảm ơn anh!
 
Hì, Em dùng từ "quanh quanh" khu đó thôi anh ạ!
Em có ý tưởng vậy, anh có hướng giải quyết thế nào chó em xin ý kiến mới để em học hỏi.
Em có tải file ở bài #9 khi kết hợp ý tưởng ở bài #7 của Thanh Bình PV.
Anh giúp em mới nhé!
Cảm ơn anh!
Sao bạn không tự thử đi, sẽ có nhiều thú vị, rồi mắc đâu upload lên đây
Hơn xa việc chờ đợi, học được nhiều điều

với gợi ý thuộc tính
.Left và .Top của Form, của range, của activeCell ....
 
Sao bạn không tự thử đi, sẽ có nhiều thú vị, rồi mắc đâu upload lên đây
Hơn xa việc chờ đợi, học được nhiều điều

với gợi ý thuộc tính
.Left và .Top của Form, của range, của activeCell ....
Mình thử rồi mà mình mới up lên nhờ mà! bài 9 mình đăng là mình đã sửa lại file rồi bạn ạ!
 
Em ẩn sheet1 đi khi chạy code thì vẫn hiện tên sheet1 lên và khi nhấn vào đó sẽ báo lỗi.
Anh có thể sửa code để những sheet đã ẩn không hiện lên khi chạy code.
Hoặc tích hợp tính năng ẩn/hiện sheet vào luôn Form này.
View attachment 229515
Đây là một cách nửa, nhưng chắc có lẽ sẽ còn lỗi, tạm thời chưa phát hiện ra. Bạn test thử nếu có vấn đề nửa thì bàn tiếp.
 

File đính kèm

Hì, Em dùng từ "quanh quanh" khu đó thôi anh ạ!
Em có ý tưởng vậy, anh có hướng giải quyết thế nào chó em xin ý kiến mới để em học hỏi.
Nhưng tôi mở tập tin thì chưa thấy bạn định hiển thị Form bằng cách nào. Chả nhẽ bằng cách vào VBE và chạy code (Run, F5)?
 
Nhưng tôi mở tập tin thì chưa thấy bạn định hiển thị Form bằng cách nào. Chả nhẽ bằng cách vào VBE và chạy code (Run, F5)?
Sẳn anh @batman1 viết code cho hiển thị Form tại vị trí con chuột cho em tham khảo với (Hiển thị tại ô đang chọn thì em có tham khảo code trên diễn đàn rồi), đụng tới cái API sao nghiễn hoài vẫn không thấm nỗi.
 
Sẳn anh @batman1 viết code cho hiển thị Form tại vị trí con chuột cho em tham khảo với (Hiển thị tại ô đang chọn thì em có tham khảo code trên diễn đàn rồi), đụng tới cái API sao nghiễn hoài vẫn không thấm nỗi.
Không ai thấm và hiểu, nhớhoàn toàn API trừ nhà sản xuất ra nó. Vì API sản xuất ra như công cụ sẵn, cứ thế áp dụng thôi
Như kiểu biết các loại ô tô, và vận dụng trường hợp nào, cùng với học lái thôi.
 
Sẳn anh @batman1 viết code cho hiển thị Form tại vị trí con chuột cho em tham khảo với (Hiển thị tại ô đang chọn thì em có tham khảo code trên diễn đàn rồi), đụng tới cái API sao nghiễn hoài vẫn không thấm nỗi.
Nếu click vào Button hay ô trên Sheet1 thì góc trên bên trái của Form sẽ ở điểm click chứ không ở góc trên bên trái của Button hay ô. Muốn góc trên bên trái của Form trùng với góc trên bên trái của ô thì phải click vào điểm ở góc trên bên trái của ô.

1. Code trong Sheet1 - chỉ là ví dụ
Mã:
Option Explicit

'vi du
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    FormInCursor UserForm1
    UserForm1.Show False
End Sub

2. Code trong Module1 - chỉ là ví dụ
Mã:
Option Explicit

'vi du
Sub Button1_Click()
    FormInCursor UserForm1    
    UserForm1.Show False
End Sub

3. Code module modFormInCursor
Mã:
Option Explicit

Private Const LOGPIXELSX = 88
Private Const LOGPIXELSY As Long = 90
Private Const POINTS_PER_INCH As Long = 72

Private Type POINTAPI
    x As Long
    y As Long
End Type

#If VBA7 Then
    Private Declare PtrSafe Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
    Private Declare PtrSafe Function GetDC Lib "user32" (ByVal hWnd As LongPtr) As LongPtr
    Private Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hWnd As LongPtr, ByVal hdc As LongPtr) As Long
    Private Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hdc As LongPtr, ByVal nIndex As Long) As Long
#Else
    Private Declare Function GetCursorPos Lib "user32.dll" (lpPoint As POINTAPI) As Long
    Private Declare Function GetDC Lib "user32.dll" (ByVal hWnd As Long) As Long
    Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hWnd As Long, ByVal hdc As Long) As Long
    Private Declare Function GetDeviceCaps Lib "gdi32.dll" (ByVal hdc As Long, ByVal nIndex As Long) As Long
#End If

Sub FormInCursor(ByVal Form As Object)
#If VBA7 Then
    Dim DC As LongPtr
#Else
    Dim DC As Long
#End If
Dim PixelsPerPointsX As Double, PixelsPerPointsY As Double, pt As POINTAPI
    DC = GetDC(0)
    PixelsPerPointsX = GetDeviceCaps(DC, LOGPIXELSX) / POINTS_PER_INCH
    PixelsPerPointsY = GetDeviceCaps(DC, LOGPIXELSY) / POINTS_PER_INCH
    ReleaseDC 0, DC
    GetCursorPos pt
    Form.Left = pt.x / PixelsPerPointsX
    Form.Top = pt.y / PixelsPerPointsY
End Sub
 
Nhưng tôi mở tập tin thì chưa thấy bạn định hiển thị Form bằng cách nào. Chả nhẽ bằng cách vào VBE và chạy code (Run, F5)?
Em Run code hoặc đặt phím tắt cho nó.
Như vậy có ổn không anh? Anh giúp em ạ!
Cảm ơn anh!
Bài đã được tự động gộp:

Đây là một cách nửa, nhưng chắc có lẽ sẽ còn lỗi, tạm thời chưa phát hiện ra. Bạn test thử nếu có vấn đề nửa thì bàn tiếp.
Vâng, em cám ơn anh!
 
Đây là một cách nửa, nhưng chắc có lẽ sẽ còn lỗi, tạm thời chưa phát hiện ra. Bạn test thử nếu có vấn đề nửa thì bàn tiếp.
Nút Commandbutton "cmd Showsheet" có tác dụng gì vậy anh?
Nó có phải dùng để chuyển ngược lại trạng thái của sheet đúng không anh?
Nó chỉ có thể chuyển trạng thái từ "ẩn" thành "Không ẩn" mà chưa có tác dụng ngược lại là chuyển trạng thái từ "không ẩn" thành "ẩn"
Trường hợp chuyển từ "ẩn" thành "Không ẩn" như sau:
Em tets qua thì thấy: Nếu để sheet1 ban đầu trạng thái ẩn, sau đó chạy code -> hiện lên giao diện Form -> chọn sheet1 -> nhấn "cmd Showsheet" -> sẽ thấy trạng thái không ẩn của sheet1 nhưng sau đó đóng giao diện Form -> Vẫn nhìn thấy sheet1 hiện lên -> chọn sang sheet khác thì sẽ thấy sheet1 lại bị ẩn.
Giao diện Form hiện lên ở giữa màn hình.
Cảm ơn anh!
 
Lần chỉnh sửa cuối:
Em Run code hoặc đặt phím tắt cho nó.
Hãy đặt phím tắt cho code cần thực hiện.

1. Nếu muốn định vị Form tại trỏ chuột thì dùng code
Mã:
DinhViFormTaiChuot UserForm1
UserForm1.Show False

2.
- Nếu muốn định vị Form tại O20
Mã:
DinhViFormTaiCell UserForm1, Range("O20"), False
UserForm1.Show False

- Nếu muốn định vị Form tại ActiveCell
Mã:
DinhViFormTaiCell UserForm1, ActiveCell, False
UserForm1.Show False

Trong 2 trường hợp trên nếu O20 hoặc ActiveCell ở gần góc dưới bên phải thì Form sẽ bị che. Nếu muốn luôn luôn nhìn thấy toàn bộ Form thì thay ở 2 code ở trên False bằng True. Lúc đó nếu cần thì cửa sổ sẽ được cuộn để luôn nhìn thấy Form. Tất nhiên nếu không cần cuộn vẫn nhìn thấy hết Form thì cửa sổ không được cuộn cho dù True.

3. Chép code sau vào Module, vd. Module1
Mã:
Option Explicit

Private Const LOGPIXELSX = 88
Private Const LOGPIXELSY As Long = 90
Private Const POINTS_PER_INCH As Long = 72

Private Type POINTAPI
    x As Long
    y As Long
End Type

#If VBA7 Then
    Private Declare PtrSafe Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
    Private Declare PtrSafe Function GetDC Lib "user32" (ByVal hWnd As LongPtr) As LongPtr
    Private Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hWnd As LongPtr, ByVal hdc As LongPtr) As Long
    Private Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hdc As LongPtr, ByVal nIndex As Long) As Long
#Else
    Private Declare Function GetCursorPos Lib "user32.dll" (lpPoint As POINTAPI) As Long
    Private Declare Function GetDC Lib "user32.dll" (ByVal hWnd As Long) As Long
    Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hWnd As Long, ByVal hdc As Long) As Long
    Private Declare Function GetDeviceCaps Lib "gdi32.dll" (ByVal hdc As Long, ByVal nIndex As Long) As Long
#End If

Sub DinhViFormTaiChuot(ByVal Form As Object)
#If VBA7 Then
    Dim DC As LongPtr
#Else
    Dim DC As Long
#End If
Dim PixelsPerPointsX As Double, PixelsPerPointsY As Double, pt As POINTAPI
    DC = GetDC(0)
    PixelsPerPointsX = GetDeviceCaps(DC, LOGPIXELSX) / POINTS_PER_INCH
    PixelsPerPointsY = GetDeviceCaps(DC, LOGPIXELSY) / POINTS_PER_INCH
    ReleaseDC 0, DC
    GetCursorPos pt
    Form.Left = pt.x / PixelsPerPointsX
    Form.Top = pt.y / PixelsPerPointsY
End Sub

Sub DinhViFormTaiCell(ByVal Form As Object, ByVal tlCell As Range, ByVal showFullForm As Boolean)
'    dinh vi Form sao cho goc tren ben trai cua Form trung voi o tlCell.
'    neu showFullForm = True thi khi can thiet thi cua so se duoc cuon de hien thi toan bo Form
'    neu showFullForm = False thi tham chi khi Form bi che khuat thi cua so khong duoc cuon.
#If VBA7 Then
    Dim DC As LongPtr
#Else
    Dim DC As Long
#End If
Dim l As Double, t As Double, r As Long, c As Long, rng As Range
Dim PixelsPerPointsX As Double, PixelsPerPointsY As Double
    ActiveWindow.Zoom = 100
    If showFullForm Then
        l = tlCell.Left + Form.Width
        t = tlCell.Top + Form.Height
        Set rng = ActiveWindow.VisibleRange(ActiveWindow.VisibleRange.Count)
        Do While tlCell.Offset(0, c).Left < l
            If tlCell.Offset(0, c).Left < l Then c = c + 1
        Loop
        If Intersect(tlCell.Offset(0, c), ActiveWindow.VisibleRange) Is Nothing Then
            ActiveWindow.SmallScroll ToRight:=tlCell.Offset(0, c).Column - rng.Column
        End If
        Do While tlCell.Offset(r).Top < t
            If tlCell.Offset(r).Top < t Then r = r + 1
        Loop
        If Intersect(tlCell.Offset(r), ActiveWindow.VisibleRange) Is Nothing Then
            ActiveWindow.SmallScroll Down:=tlCell.Offset(r).Row - rng.Row
        End If
    End If
    DC = GetDC(0)
    PixelsPerPointsX = GetDeviceCaps(DC, LOGPIXELSX) / POINTS_PER_INCH
    PixelsPerPointsY = GetDeviceCaps(DC, LOGPIXELSY) / POINTS_PER_INCH
    ReleaseDC 0, DC
    Form.StartUpPosition = 0
    Form.Left = ActiveWindow.PointsToScreenPixelsX(tlCell.Left * PixelsPerPointsX) / PixelsPerPointsX
    Form.Top = ActiveWindow.PointsToScreenPixelsY(tlCell.Top * PixelsPerPointsY) / PixelsPerPointsY
End Sub
 
Nếu click vào Button hay ô trên Sheet1 thì góc trên bên trái của Form sẽ ở điểm click chứ không ở góc trên bên trái của Button hay ô. Muốn góc trên bên trái của Form trùng với góc trên bên trái của ô thì phải click vào điểm ở góc trên bên trái của ô.

1. Code trong Sheet1 - chỉ là ví dụ
Mã:
Option Explicit

'vi du
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    FormInCursor UserForm1
    UserForm1.Show False
End Sub

2. Code trong Module1 - chỉ là ví dụ
Mã:
Option Explicit

'vi du
Sub Button1_Click()
    FormInCursor UserForm1   
    UserForm1.Show False
End Sub

3. Code module modFormInCursor
Mã:
Option Explicit

Private Const LOGPIXELSX = 88
Private Const LOGPIXELSY As Long = 90
Private Const POINTS_PER_INCH As Long = 72

Private Type POINTAPI
    x As Long
    y As Long
End Type

#If VBA7 Then
    Private Declare PtrSafe Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
    Private Declare PtrSafe Function GetDC Lib "user32" (ByVal hWnd As LongPtr) As LongPtr
    Private Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hWnd As LongPtr, ByVal hdc As LongPtr) As Long
    Private Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hdc As LongPtr, ByVal nIndex As Long) As Long
#Else
    Private Declare Function GetCursorPos Lib "user32.dll" (lpPoint As POINTAPI) As Long
    Private Declare Function GetDC Lib "user32.dll" (ByVal hWnd As Long) As Long
    Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hWnd As Long, ByVal hdc As Long) As Long
    Private Declare Function GetDeviceCaps Lib "gdi32.dll" (ByVal hdc As Long, ByVal nIndex As Long) As Long
#End If

Sub FormInCursor(ByVal Form As Object)
#If VBA7 Then
    Dim DC As LongPtr
#Else
    Dim DC As Long
#End If
Dim PixelsPerPointsX As Double, PixelsPerPointsY As Double, pt As POINTAPI
    DC = GetDC(0)
    PixelsPerPointsX = GetDeviceCaps(DC, LOGPIXELSX) / POINTS_PER_INCH
    PixelsPerPointsY = GetDeviceCaps(DC, LOGPIXELSY) / POINTS_PER_INCH
    ReleaseDC 0, DC
    GetCursorPos pt
    Form.Left = pt.x / PixelsPerPointsX
    Form.Top = pt.y / PixelsPerPointsY
End Sub
A giúp e vấn đề ở #7 với ạ. e cảm ơn.
 
Vâng cảm ơn anh!
Code trong 1. và 2. thì copy vào module hay code trong Form vậy anh?
Nếu là bạn hỏi tôi thì bạn trích sai bài. Hãy cẩn thận hơn.

Code 1, 2 thì đưa vào chỗ nào cần gọi Form thôi. Nhưng làm gì có chuyện code gọi UserForm1 lại đưa vào module UserForm1? Chịu khó suy nghĩ chút nhé.

Còn chỗ gọi thì tùy. Ví dụ bạn muốn chọn cell nào đó thì hiển thì ngay Form ở cell đó thì code trong module vd. Sheet1.
Mã:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    DinhViFormTaiCell UserForm1, Target, True
    UserForm1.Show False
End Sub

Nếu có code trong vd. Module2
Mã:
Sub ShowForm()
    DinhViFormTaiCell UserForm1, ActiveCell, True
    UserForm1.Show False
End Sub
và gán cho nó phím tắt thì mỗi khi nhấn phím tắt thì Form sẽ được hiển thị tại ô đang được chọn.

Nếu có code trong vd. Module2
Mã:
Sub ShowForm()
    DinhViFormTaiCell UserForm1, ActiveSheet.Range("B5"), True
    UserForm1.Show False
End Sub
và gán cho nó phím tắt thì mỗi khi nhấn phím tắt thì Form sẽ được hiển thị tại ô B5 trong Sheet đang hoạt động.

Vân vân và mây mây.

Code hiển thị Form là code hiển thị Form. Còn chuyện gọi nó ở đâu là vấn đề suy nghĩ lôgíc. Chịu khó suy nghĩ bạn nhé.

Tôi kết thúc ở đây.
 
Nếu là bạn hỏi tôi thì bạn trích sai bài. Hãy cẩn thận hơn.

Code 1, 2 thì đưa vào chỗ nào cần gọi Form thôi. Nhưng làm gì có chuyện code gọi UserForm1 lại đưa vào module UserForm1? Chịu khó suy nghĩ chút nhé.

Còn chỗ gọi thì tùy. Ví dụ bạn muốn chọn cell nào đó thì hiển thì ngay Form ở cell đó thì code trong module vd. Sheet1.
Mã:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    DinhViFormTaiCell UserForm1, Target, True
    UserForm1.Show False
End Sub

Nếu có code trong vd. Module2
Mã:
Sub ShowForm()
    DinhViFormTaiCell UserForm1, ActiveCell, True
    UserForm1.Show False
End Sub
và gán cho nó phím tắt thì mỗi khi nhấn phím tắt thì Form sẽ được hiển thị tại ô đang được chọn.

Nếu có code trong vd. Module2
Mã:
Sub ShowForm()
    DinhViFormTaiCell UserForm1, ActiveSheet.Range("B5"), True
    UserForm1.Show False
End Sub
và gán cho nó phím tắt thì mỗi khi nhấn phím tắt thì Form sẽ được hiển thị tại ô B5 trong Sheet đang hoạt động.

Vân vân và mây mây.

Code hiển thị Form là code hiển thị Form. Còn chuyện gọi nó ở đâu là vấn đề suy nghĩ lôgíc. Chịu khó suy nghĩ bạn nhé.

Tôi kết thúc ở đây.
Em cám ơn anh! anh ơi em có làm như anh hướng dẫn khi chạy code thấy báo lỗi:
Phiền anh làm mẫu luôn trong file em đính kèm được không ạ?
Em thử mãi mà vẫn báo lỗi
Anh xem giúp em mới ạ!
2222.png
 

File đính kèm

Lần chỉnh sửa cuối:
Em cám ơn anh! anh ơi em có làm như anh hướng dẫn khi chạy code thấy báo lỗi:
Phiền anh làm mẫu luôn trong file em đính kèm được không ạ?
Em thử mãi mà vẫn báo lỗi
Anh xem giúp em mới ạ!
View attachment 229564
Trong code của tôi toàn bộ các dòng kể từ dòng
Mã:
Private Const LOGPIXELSX = 88
cho tới
Mã:
    Private Declare Function GetDeviceCaps Lib "gdi32.dll" (ByVal hdc As Long, ByVal nIndex As Long) As Long
#End If

là phầi khai báo.

Những code của mình bạn phải đặt sau phần khai báo. Tức cả cụm
Mã:
Public vValue As Integer
Sub MenuSheet()
    Call FrmShowSheet.Show(0)
End Sub
Sub ShowForm()
    DinhViFormTaiCell FrmShowSheet, ActiveCell, True
    FrmShowSheet.Show False
End Sub

bạn phải đặt sau phần khai báo. Tức sau
Mã:
    Private Declare Function GetDeviceCaps Lib "gdi32.dll" (ByVal hdc As Long, ByVal nIndex As Long) As Long
#End If

Trong tương lai nếu bạn khai báo các hàm API thì bạn cũng phải đặt chúng ở phần đầu. Tất cả các sub / function của mình bạn phải đặt sau phần khai báo. Không thể đặt chúng trước các khai báo API hoặc đan xen với chúng. Khai báo ở trên cùng, còn các sub bạn viết phải đặt sau phần khai báo.

2 sub trên của bạn không nhất thiết phải đặt ngay sau phần khai báo. Chúng phải ở sau phần khai báo, ở chỗ nào cũng được miễn là sau phần khai báo. Vd. đặt chúng ở sau tất cả các code của tôi, tức sau
Mã:
Form.Top = ActiveWindow.PointsToScreenPixelsY(tlCell.Top * PixelsPerPointsY) / PixelsPerPointsY
End Sub

Lưu ý: Sub ShowForm bạn phải gọi từ Button hoặc từ phím tắt hoặc từ vd. Sub Worksheet_SelectionChange. Tức gọi khi bạn đang thao tác trên sheet. Bạn không thể vào VBE để gọi, vì lúc đó sẽ không có tác dụng. Tức chỉ hiển thị Form nhưng không định vị vào cell mong muốn.
 
Trong code của tôi toàn bộ các dòng kể từ dòng
Mã:
Private Const LOGPIXELSX = 88
cho tới
Mã:
    Private Declare Function GetDeviceCaps Lib "gdi32.dll" (ByVal hdc As Long, ByVal nIndex As Long) As Long
#End If

là phầi khai báo.

Những code của mình bạn phải đặt sau phần khai báo. Tức cả cụm
Mã:
Public vValue As Integer
Sub MenuSheet()
    Call FrmShowSheet.Show(0)
End Sub
Sub ShowForm()
    DinhViFormTaiCell FrmShowSheet, ActiveCell, True
    FrmShowSheet.Show False
End Sub

bạn phải đặt sau phần khai báo. Tức sau
Mã:
    Private Declare Function GetDeviceCaps Lib "gdi32.dll" (ByVal hdc As Long, ByVal nIndex As Long) As Long
#End If

Trong tương lai nếu bạn khai báo các hàm API thì bạn cũng phải đặt chúng ở phần đầu. Tất cả các sub / function của mình bạn phải đặt sau phần khai báo. Không thể đặt chúng trước các khai báo API hoặc đan xen với chúng. Khai báo ở trên cùng, còn các sub bạn viết phải đặt sau phần khai báo.

2 sub trên của bạn không nhất thiết phải đặt ngay sau phần khai báo. Chúng phải ở sau phần khai báo, ở chỗ nào cũng được miễn là sau phần khai báo. Vd. đặt chúng ở sau tất cả các code của tôi, tức sau
Mã:
Form.Top = ActiveWindow.PointsToScreenPixelsY(tlCell.Top * PixelsPerPointsY) / PixelsPerPointsY
End Sub

Lưu ý: Sub ShowForm bạn phải gọi từ Button hoặc từ phím tắt hoặc từ vd. Sub Worksheet_SelectionChange. Tức gọi khi bạn đang thao tác trên sheet. Bạn không thể vào VBE để gọi, vì lúc đó sẽ không có tác dụng. Tức chỉ hiển thị Form nhưng không định vị vào cell mong muốn.
Cảm ơn anh! em chỉ biết làm theo anh hướng dẫn, một số "thuật ngữ" anh dùng em được nghe đến lần đầu.
Em đặt code khai báo như sau
Mã:
'Khai bao
Option Explicit
Private Const LOGPIXELSX = 88
Private Const LOGPIXELSY As Long = 90
Private Const POINTS_PER_INCH As Long = 72

Private Type POINTAPI
    x As Long
    y As Long
End Type

#If VBA7 Then
    Private Declare PtrSafe Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
    Private Declare PtrSafe Function GetDC Lib "user32" (ByVal hWnd As LongPtr) As LongPtr
    Private Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hWnd As LongPtr, ByVal hdc As LongPtr) As Long
    Private Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hdc As LongPtr, ByVal nIndex As Long) As Long
#Else
    Private Declare Function GetCursorPos Lib "user32.dll" (lpPoint As POINTAPI) As Long
    Private Declare Function GetDC Lib "user32.dll" (ByVal hWnd As Long) As Long
    Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hWnd As Long, ByVal hdc As Long) As Long
    Private Declare Function GetDeviceCaps Lib "gdi32.dll" (ByVal hdc As Long, ByVal nIndex As Long) As Long
#End If
Sau đó đến đoạn code anh hướng dẫn chèn sau đoạn khai báo:
Mã:
'Code cua minh
Public vValue As Integer
Sub MenuSheet()
    Call FrmShowSheet.Show(0)
End Sub
Sub ShowForm()
    DinhViFormTaiCell FrmShowSheet, ActiveCell, True
    FrmShowSheet.Show False
End Sub
Em vẫn thấy lỗi.

Là do đậu vậy anh nhỉ, em có làm sai không ạ?
loi.png
 

File đính kèm

Cảm ơn anh! em chỉ biết làm theo anh hướng dẫn, một số "thuật ngữ" anh dùng em được nghe đến lần đầu.
Em đặt code khai báo như sau
Mã:
'Khai bao
Option Explicit
Private Const LOGPIXELSX = 88
Private Const LOGPIXELSY As Long = 90
Private Const POINTS_PER_INCH As Long = 72

Private Type POINTAPI
    x As Long
    y As Long
End Type

#If VBA7 Then
    Private Declare PtrSafe Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
    Private Declare PtrSafe Function GetDC Lib "user32" (ByVal hWnd As LongPtr) As LongPtr
    Private Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hWnd As LongPtr, ByVal hdc As LongPtr) As Long
    Private Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hdc As LongPtr, ByVal nIndex As Long) As Long
#Else
    Private Declare Function GetCursorPos Lib "user32.dll" (lpPoint As POINTAPI) As Long
    Private Declare Function GetDC Lib "user32.dll" (ByVal hWnd As Long) As Long
    Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hWnd As Long, ByVal hdc As Long) As Long
    Private Declare Function GetDeviceCaps Lib "gdi32.dll" (ByVal hdc As Long, ByVal nIndex As Long) As Long
#End If
Sau đó đến đoạn code anh hướng dẫn chèn sau đoạn khai báo:
Mã:
'Code cua minh
Public vValue As Integer
Sub MenuSheet()
    Call FrmShowSheet.Show(0)
End Sub
Sub ShowForm()
    DinhViFormTaiCell FrmShowSheet, ActiveCell, True
    FrmShowSheet.Show False
End Sub
Em vẫn thấy lỗi.

Là do đậu vậy anh nhỉ, em có làm sai không ạ?
View attachment 229574
Thế những code của tôi từ dòng
Mã:
Sub DinhViFormTaiChuot(ByVal Form As Object)

tới dòng
Mã:
Form.Top = ActiveWindow.PointsToScreenPixelsY(tlCell.Top * PixelsPerPointsY) / PixelsPerPointsY
End Sub

bạn vứt đi đâu rồi?

Tôi viết là

... bạn phải đặt sau phần khai báo. Tức sau
Mã:
    Private Declare Function GetDeviceCaps Lib "gdi32.dll" (ByVal hdc As Long, ByVal nIndex As Long) As Long
#End If

và
2 sub trên của bạn không nhất thiết phải đặt ngay sau phần khai báo. Chúng phải ở sau phần khai báo, ở chỗ nào cũng được miễn là sau phần khai báo. Vd. đặt chúng ở sau tất cả các code của tôi, tức sau
Mã:
Form.Top = ActiveWindow.PointsToScreenPixelsY(tlCell.Top * PixelsPerPointsY) / PixelsPerPointsY
End Sub

Nhưng làm gì có chỗ nào tôi viết là phải vứt một phần code đi đâu? Nhất là dòng đỏ cho thấy là toàn bộ code của tôi phải có, còn code của bạn đặt sau chúng.

Tôi không làm hộ bạn mà chỉ hướng dẫn để bạn tự làm. Như thế về sau bạn mới biết làm. Nhưng bạn đọc không suy nghĩ (chỗ đỏ).

Tôi dừng tại đây, dù bạn làm được hay không.
 
Thế những code của tôi từ dòng
Mã:
Sub DinhViFormTaiChuot(ByVal Form As Object)

tới dòng
Mã:
Form.Top = ActiveWindow.PointsToScreenPixelsY(tlCell.Top * PixelsPerPointsY) / PixelsPerPointsY
End Sub

bạn vứt đi đâu rồi?

Tôi viết là



và


Nhưng làm gì có chỗ nào tôi viết là phải vứt một phần code đi đâu? Nhất là dòng đỏ cho thấy là toàn bộ code của tôi phải có, còn code của bạn đặt sau chúng.

Tôi không làm hộ bạn mà chỉ hướng dẫn để bạn tự làm. Như thế về sau bạn mới biết làm. Nhưng bạn đọc không suy nghĩ (chỗ đỏ).

Tôi dừng tại đây, dù bạn làm được hay không.
Dạ! em làm được rồi. cám ơn anh nhiều!
Bài đã được tự động gộp:

Đây là một cách nửa, nhưng chắc có lẽ sẽ còn lỗi, tạm thời chưa phát hiện ra. Bạn test thử nếu có vấn đề nửa thì bàn tiếp.
Giả sử các sheet đều bị ẩn hết, chỉ còn lại hiện lại duy nhất 1 sheet (sheet1)
Khi đó tác động vào giao diện tên sheet trong giao diện Form cũng bị báo lỗi anh ạ!
34.png45.png
 
Lần chỉnh sửa cuối:
Dạ! em làm được rồi. cám ơn anh nhiều!
Bài đã được tự động gộp:


Giả sử các sheet đều bị ẩn hết, chỉ còn lại hiện lại duy nhất 1 sheet (sheet1)
Khi đó tác động vào giao diện tên sheet trong giao diện Form cũng bị báo lỗi anh ạ!
View attachment 229577View attachment 229578
Bạn xem lại file, tại tôi sửa từ file có sẳn chứ theo tôi thì không nên dùng nút lệnh cmdShowSheet trong sheet (Nó bị thừa)
 

File đính kèm

Bạn xem lại file, tại tôi sửa từ file có sẳn chứ theo tôi thì không nên dùng nút lệnh cmdShowSheet trong sheet (Nó bị thừa)
Cảm ơn anh!
Anh cho em hỏi khi chạy form thì có nút màu xanh xanh mà chỉ có tác dụng trong sheet1 hiện ra như hình em đăng để làm gì vậy ạ?
Em xóa hình xanh xanh đó ở sheet1 đi có ảnh hưởng gì không ạ?
Và Sheet "siêu ẩn" ở đây là những sheet như thế nào ạ?
nh.png
 
Lần chỉnh sửa cuối:
Cảm ơn anh!
Anh cho em hỏi khi chạy form thì có nút màu xanh xanh mà chỉ có tác dụng trong sheet1 hiện ra như hình em đăng để làm gì vậy ạ?
Em xóa hình xanh xanh đó ở sheet1 đi có ảnh hưởng gì không ạ?
Và Sheet "siêu ẩn" ở đây là những sheet như thế nào ạ?
View attachment 229732
Nút màu xanh là để test code thôi, bạn có thể xóa nó. Còn sheet siêu ẩn bạn tự tìm hiểu nhé, gợi ý cho bạn là click phải vào sheet tab và chọn Unhide và nhìn xem có cái sheet siêu ẩn hay không.
 

Bài viết mới nhất

Back
Top Bottom