Tự động chèn code vào sheet của 1 File Excel

Liên hệ QC

Quang_Hải

Thành viên gạo cội
Tham gia
21/2/09
Bài viết
6,070
Được thích
7,992
Nghề nghiệp
Làm đủ thứ
Mình mở chủ đề này để giới thiệu cho các bạn nào quan tâm đến việc tự động chèn code vào 1 file excel nào đó.
Giả định trên file hiện tại có 1 sheet mang tên là "ABC", giờ ta muốn chèn code vào sheet này
Để phát triển thêm ta có thể thay ActiveWorkBook bằng tên của File ta cần chèn code
PHP:
Sub add_code_to_existing_sheet()
Dim CodeLines As Long, sheetCode
   sheetCode = ActiveWorkbook.Sheets("ABC").CodeName
   With ActiveWorkbook.VBProject.VBComponents(sheetCode).CodeModule
        CodeLines = .CountOfLines + 1
        .InsertLines CodeLines, _
            "Private Sub Worksheet_SelectionChange(ByVal Target As Range)" & Chr(13) & _
            "     MsgBox ""Code Created"" " & Chr(13) & _
            "End Sub"
    End With
End Sub
Ta cũng có thể tạo ra 1 sheet mới rồi chèn code vào sheet vừa được tạo bằng code bên dưới.
PHP:
Sub add_code_to_NewSheet()
Dim CodeLines As Long
   Sheets.Add
   With ActiveWorkbook.VBProject.VBComponents(ActiveSheet.CodeName).CodeModule
        CodeLines = .CountOfLines + 1
        .InsertLines CodeLines, _
            "Private Sub Worksheet_SelectionChange(ByVal Target As Range)" & Chr(13) & _
            "     msgbox ""Code Created"" " & Chr(13) & _
            "End Sub"
    End With
End Sub
Nếu cần chèn code vào WorkBook ta áp dụng code này
PHP:
Sub add_code_to_thisworkbook()
Dim CodeLines As Long
   With ActiveWorkbook.VBProject.VBComponents("Thisworkbook").CodeModule
        CodeLines = .CountOfLines + 1
        .InsertLines CodeLines, _
            "Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)" & Chr(13) & _
            "     msgbox ""Code Created"" " & Chr(13) & _
            "End Sub"
    End With
End Sub
Nếu cần thêm 1 module mới rồi chèn code vào module này thì ta làm như code bên dưới.
Chú ý: Để chèn được Module thì phải vào Tools, tìm và chọn mục Microsoft Visual Basic for Appliations extensibility 5.3
Hoặc khi viết code đến dòng ActiveWorkbook.VBProject.VBComponents.Add(vbext_ct_StdModule) thì Excel sẽ tự động hỏi mình có muốn chọn mục này hay không.
PHP:
Sub Add_Module_and_Code()
Dim CodeLines As Long, VBComp
   Set VBComp = ActiveWorkbook.VBProject.VBComponents.Add(vbext_ct_StdModule)
   With ActiveWorkbook.VBProject.VBComponents(VBComp.Name).CodeModule
        CodeLines = .CountOfLines + 1
        .InsertLines CodeLines, _
            "Sub Add_Module_and_Code" & Chr(13) & _
            "     msgbox ""Code Created"" " & Chr(13) & _
            "End Sub"
    End With
End Sub

Hy vọng là bài viết hữu ích cho những bạn mới học VBA
 
Lần chỉnh sửa cuối:
Flow của chương trình như sau
1. Nạp Mở file workbook
2. Tạo một file REG và chạy nó thay đổi trong registry nhằm tạo đánh lừa là cái Policy đã được thiết lập
3. Xóa nó đi, để tránh hiển thị bị mờ.
4. Nạp lại đăng ký cho hai giá trị Macro và Trust. (Bước này không có chắc cũng không sao)
5. Bật cái khung hiển thị thiết lập trong macro (Vì MS nó chỉ active cái Application.Volatile khi khung này được bật)
6. Dùng sendkey OK để tắt nó đi (Để tránh hiển thị chớp nháy thì cho thêm một xử lý kiểm soát, và không cho báo Alert)
7. Để kiểm tra đúng hay chưa em sẽ thêm một add một hàm kiểm tra vào ô A1.
8. Vì ô này chỉ chạy giá trị khi nó được update nên sau khi chèn Fomula thì cần sendkey Enter.

Vậy thôi. Các bác muốn test cũng được, không em cũng không dám làm phiền.
Nếu dùng Sendkeys thì rất nhiều bài ở trên đã nói hết cả rồi. Tôi dùng Sendkeys còn gọn hơn code của bạn nữa đó.
Vấn đề ở đây là: Không cho dùng Sendkeys thì có làm được không? Thế mới nói chứ!
 
Upvote 0
Mọi người cho ý kiến về đoạn code này nghen, không sử dụng SendKey
Mã:
Sub CheckTrustAccessToVBA()
Open "D:\Register.Reg" For Output As 1
Print #1, "REGEDIT4" & vbNewLine & _
"[HKEY_CURRENT_USER\Software\Microsoft\Office\" & Application.Version & _
"\Excel\Security]" & vbNewLine & """AccessVBOM""" & "=dword:00000001"
Close #1
Open "D:\temp.bat" For Output As 2
Print #2, "regedit /s D:\Register.Reg" & vbNewLine & _
"Del D:\Register.Reg" & vbNewLine & "Del D:\temp.bat"
Close #2
Shell ("D:\temp.bat")
End Sub
 
Upvote 0
Mọi người cho ý kiến về đoạn code này nghen, không sử dụng SendKey
Mã:
Sub CheckTrustAccessToVBA()
Open "D:\Register.Reg" For Output As 1
Print #1, "REGEDIT4" & vbNewLine & _
"[HKEY_CURRENT_USER\Software\Microsoft\Office\" & Application.Version & _
"\Excel\Security]" & vbNewLine & """AccessVBOM""" & "=dword:00000001"
Close #1
Open "D:\temp.bat" For Output As 2
Print #2, "regedit /s D:\Register.Reg" & vbNewLine & _
"Del D:\Register.Reg" & vbNewLine & "Del D:\temp.bat"
Close #2
Shell ("D:\temp.bat")
End Sub
Hình như có gì đó... sai sai nên nó hổng có chạy (báo lỗi)
???
 
Upvote 0
Có anh chị em nào rảnh rảnh thử chạy đoạn code bài 84 coi sao nhé.
Anh NDU kiểm xem coi máy anh có ổ D không. Em đoán có thể lỗi do máy không có ổ đĩa D
 
Upvote 0
Hình như có gì đó... sai sai nên nó hổng có chạy (báo lỗi)
???
Trên máy Em chạy OK nhưng kiểm tra VBATrusted = False ...Nếu dùng thêm Sendkeys mở dòm cái Trust Acces 1 cái nữa thì ok .... kẹt cái không cho dùng Sendkeys
Như em nói Ý 2 bài #64 ấy ...........Nếu làm được thì hết nói
 
Upvote 0
Dùng sendkey thì nói làm gì. Thiên hạ họ kêu tốt nhất trong lập trình không dùng. Thà rằng tìm cách bật cái hộp thoại đó nên, rồi dùng mấy cái api sendmessage gì gì đấy để check.

Vấn đề ở chỗ ta can thiệp vào reg nhưng vba không chịu aupdate thông tin cho ta ngay lúc đó. nó không chịu update thì hết thuốc.
 
Upvote 0
Dùng sendkey thì nói làm gì. Thiên hạ họ kêu tốt nhất trong lập trình không dùng. Thà rằng tìm cách bật cái hộp thoại đó nên, rồi dùng mấy cái api sendmessage gì gì đấy để check.

Vấn đề ở chỗ ta can thiệp vào reg nhưng vba không chịu aupdate thông tin cho ta ngay lúc đó. nó không chịu update thì hết thuốc.
Thử nghiên cứu ý 2 bài 64 xem tình hình sao ??!!
@ThangCuAnh keo làm được nhưng làm biếng hay sao ý :p:D
 
Upvote 0
Nếu dùng Sendkeys thì rất nhiều bài ở trên đã nói hết cả rồi. Tôi dùng Sendkeys còn gọn hơn code của bạn nữa đó.
Vấn đề ở đây là: Không cho dùng Sendkeys thì có làm được không? Thế mới nói chứ!

Cho em biết tại sao anh không muốn dùng SendKeys?
 

File đính kèm

Upvote 0
Cho em biết tại sao anh không muốn dùng SendKeys?
Tôi đâu có muốn gì đâu!
Thực chất bài này tôi dùng Sendkeys và đã giải quyết xong rồi. Vấn đề là mọi người đang đố nhau xem ai có khả năng "xơi" được mà không dùng Sendkeys ấy chứ
 
Upvote 0
Upvote 0
Khác nhau giữa nhấn Ok và Cancel là gì nhỉ. Giả dụ mặc định là False thì khi tắt hoặc nhấn cancel nó sẽ không update sang true, khi nhấn Ok nó sẽ thay đôir trạng thái tín hiệu sang True. Giả dụ cái này quản lý trong file vb7 thì nó sẽ phải tạo một bản backup và sử dụng bản backup có tên vb71 đó. Em từng mở một file excel có 2 workbook trong dod cod tên ửokbook cho bản cũ và workbook1 cho bản mới. Nên về cơ bản nếu lấy file Vb71 lúc thay đổi và nạp lại cho nó, đăng ký lại registry bằng cái đó chắc khỏi cần change ok. Em chỉ đưa ra nhận định.
 
Upvote 0
Khác nhau giữa nhấn Ok và Cancel là gì nhỉ. Giả dụ mặc định là False thì khi tắt hoặc nhấn cancel nó sẽ không update sang true, khi nhấn Ok nó sẽ thay đôir trạng thái tín hiệu sang True. Giả dụ cái này quản lý trong file vb7 thì nó sẽ phải tạo một bản backup và sử dụng bản backup có tên vb71 đó. Em từng mở một file excel có 2 workbook trong dod cod tên ửokbook cho bản cũ và workbook1 cho bản mới. Nên về cơ bản nếu lấy file Vb71 lúc thay đổi và nạp lại cho nó, đăng ký lại registry bằng cái đó chắc khỏi cần change ok. Em chỉ đưa ra nhận định.
Thế thử bỏ sendkey đi chỉ dùng caia reg để thay đổi. thay đổi xong thì tạo mới một cái application ( new application), rồi kiểm tra xem trên cái cửa sổ mới nó có nhận thiết lập mới không.
 
Upvote 0
Thế thử bỏ sendkey đi chỉ dùng caia reg để thay đổi. thay đổi xong thì tạo mới một cái application ( new application), rồi kiểm tra xem trên cái cửa sổ mới nó có nhận thiết lập mới không.
Vậy giả thuyết âm mưu là MS có một thuật toán thay đổi trạng thái khi nhấn đúng vào button OK. Chỉ khi đó file VB71 mới được tạo. Vậy thao để có file Vb71 đó phải được dùng ít nhất một lần nhấn nút OK. Điều này sẽ không vấn đề nếu chỉ dùng một máy và vb7 không có ràng buộc về máy tính cài nó. Nếu có thì bên phía User phải lấy file đó 1 lần bằng cách nhấn Ok nên sendkey hầu như là khó thay đổi đc :(
 
Upvote 0
Bà con test lại giúp tui với, xem nó chạy ra sao, đúng ý chưa. Nếu failed thì nhớ cho em cái giá trị MsgBox lên của hàm CheckToken nhé
 

File đính kèm

Upvote 0
Bà con test lại giúp tui với, xem nó chạy ra sao, đúng ý chưa. Nếu failed thì nhớ cho em cái giá trị MsgBox lên của hàm CheckToken nhé
Hiện tại nó đang bị ẩn cái Trust vì đăng ký trực tiếp trong Policies. Nếu sau khi chạy enable Trust xong lại xóa cái Policies đi để khỏi bị ẩn thì điều gì sẽ xảy ra anh.
 
Upvote 0
Như Mình đã nói ở bài # 92
Mạnh mượn code bài # 84 Của Anh Quanghai1969 và Code Bài # 12 của Anh Siwtom Link sau để để xử lý Check VBOM mà không xài Sendkeys

http://www.giaiphapexcel.com/diendan/threads/chạy-runas-ứng-dụng-trong-vba.90007/

Ghi Chú:
Máy Mạnh tạo 2 User và chạy code trên User Guest
User : Administrator - Pass là: 023166 Áp dụng cho Chữ To màu đỏ sau

Call RunAsUser("Administrator", "023166", "Domain", "D:\temp.bat", False)

Nhờ các bạn thử test dùm xem sao

Mã:
Private Const LOGON_WITH_PROFILE As Long = &H1
Private Const LOGON_NETCREDENTIALS_ONLY = &H2
Private Const LOGON32_LOGON_INTERACTIVE = 2
Private Const LOGON32_PROVIDER_DEFAULT = 0
Private Const INFINITE As Long = &HFFFFFFFF
Private Type STARTUPINFOW
    cb As Long
    lpReserved As Long
    lpDesktop As Long
    lpTitle As Long
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Byte
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
End Type
Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessId As Long
    dwThreadId As Long
End Type
Private Declare Function CreateProcessWithLogonW Lib "advapi32" (ByVal UserName As String, _
ByVal domain As String, ByVal Password As String, ByVal dwLogonFlags As Long, _
ByVal ApplicationName As String, ByVal strCommandLine As Long, ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, ByVal strCurrentDirectory As Long, ByRef lpStartupInfo As STARTUPINFOW, _
ByRef lppiProcessInfo As PROCESS_INFORMATION) As Long
Private Declare Function ShellExecute Lib "Shell32.dll" Alias "ShellExecuteA" _
            (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _
            ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
          
Private Declare Function WaitForSingleObject Lib "kernel32.dll" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
          
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Rem ==========
Public Function RunAsUser(ByVal UserName As String, ByVal Password As String, _
    ByVal DomainName As String, AppName As String, Optional ByVal Wait As Boolean = False) As Long
    Dim si As STARTUPINFOW
    Dim pi As PROCESS_INFORMATION
  
    Dim wUser As String
    Dim wDomain As String
    Dim wPassword As String
    Dim wAppName As String
    Dim Result As Long
  
    si.cb = Len(si)
    wUser = StrConv(UserName & Chr(0), vbUnicode)
    wDomain = StrConv(DomainName & Chr(0), vbUnicode)
    wPassword = StrConv(Password & Chr(0), vbUnicode)
    wAppName = StrConv(AppName & Chr(0), vbUnicode)
  
    Result = CreateProcessWithLogonW(wUser, wDomain, wPassword, _
          LOGON_WITH_PROFILE, wAppName, 0, 0, 0, 0, si, pi)
    If Result <> 0 Then ''thanh cong
        Rem neu Wait  TRUE thi code dung o dong WaitForSingleObject cho toi khi process cua wAppName ket thuc
        Rem sau do moi chay tiep code CloseHandle pi.hThread
        If Wait Then WaitForSingleObject pi.hProcess, INFINITE
        CloseHandle pi.hThread
        CloseHandle pi.hProcess
        RunAsUser = 0
    Else
        Rem that bai
        RunAsUser = Err.LastDllError
        MsgBox "CreateProcessWithLogonW that bai " & Err.LastDllError, vbExclamation
    End If
End Function
Rem ==========
Private Function IsVBATrusted() As Boolean
    Application.Volatile
    On Error Resume Next
    IsVBATrusted = Not ThisWorkbook.VBProject Is Nothing
End Function
Rem ==========
Private Sub CheckTrustAccessToVBA()
    Open "D:\Register.Reg" For Output As 1
    Print #1, "REGEDIT4" & vbNewLine & _
    "[HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Office\" & Application.Version & _
    "\Excel\Security]" & vbNewLine & """AccessVBOM""" & "=dword:00000001"
    Close #1
    Open "D:\temp.bat" For Output As 2
    Print #2, "regedit /s D:\Register.Reg" & vbNewLine & _
    "Del D:\Register.Reg" & vbNewLine & "Del D:\temp.bat"
    Close #2
    Call RunAsUser("Administrator", "023166", "Domain", "D:\temp.bat", False)
End Sub
Rem ==========
Private Sub UnCheckTrustAccessToVBA()
    Open "D:\Register.Reg" For Output As 1
    Print #1, "REGEDIT4" & vbNewLine & _
    "[HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Office\" & Application.Version & _
    "\Excel\Security]" & vbNewLine & """AccessVBOM""" & "=dword:00000000"
    Close #1
    Open "D:\temp.bat" For Output As 2
    Print #2, "regedit /s D:\Register.Reg" & vbNewLine & _
    "Del D:\Register.Reg" & vbNewLine & "Del D:\temp.bat"
    Close #2
    Call RunAsUser("Administrator", "023166", "Domain", "D:\temp.bat", False)
End Sub
Rem ==========
Private Sub Test_IsVBATrusted()
    MsgBox IsVBATrusted
End Sub
Thật ra code các Bác trên GPE viết mọi cái gần như có hết rồi vấn đề là ta có biết Copy mà vận dụng vào thực tiễn hay không đó thui ...........
 

File đính kèm

Upvote 0
Như Mình đã nói ở bài # 92
Mạnh mượn code bài # 84 Của Anh Quanghai1969 và Code Bài # 12 của Anh Siwtom Link sau để để xử lý Check VBOM mà không xài Sendkeys

http://www.giaiphapexcel.com/diendan/threads/chạy-runas-ứng-dụng-trong-vba.90007/

Ghi Chú:
Máy Mạnh tạo 2 User và chạy code trên User Guest
User : Administrator - Pass là: 023166 Áp dụng cho Chữ To màu đỏ sau

Call RunAsUser("Administrator", "023166", "Domain", "D:\temp.bat", False)

Nhờ các bạn thử test dùm xem sao

Mã:
Private Const LOGON_WITH_PROFILE As Long = &H1
Private Const LOGON_NETCREDENTIALS_ONLY = &H2
Private Const LOGON32_LOGON_INTERACTIVE = 2
Private Const LOGON32_PROVIDER_DEFAULT = 0
Private Const INFINITE As Long = &HFFFFFFFF
Private Type STARTUPINFOW
    cb As Long
    lpReserved As Long
    lpDesktop As Long
    lpTitle As Long
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Byte
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
End Type
Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessId As Long
    dwThreadId As Long
End Type
Private Declare Function CreateProcessWithLogonW Lib "advapi32" (ByVal UserName As String, _
ByVal domain As String, ByVal Password As String, ByVal dwLogonFlags As Long, _
ByVal ApplicationName As String, ByVal strCommandLine As Long, ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, ByVal strCurrentDirectory As Long, ByRef lpStartupInfo As STARTUPINFOW, _
ByRef lppiProcessInfo As PROCESS_INFORMATION) As Long
Private Declare Function ShellExecute Lib "Shell32.dll" Alias "ShellExecuteA" _
            (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _
            ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
         
Private Declare Function WaitForSingleObject Lib "kernel32.dll" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
         
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Rem ==========
Public Function RunAsUser(ByVal UserName As String, ByVal Password As String, _
    ByVal DomainName As String, AppName As String, Optional ByVal Wait As Boolean = False) As Long
    Dim si As STARTUPINFOW
    Dim pi As PROCESS_INFORMATION
 
    Dim wUser As String
    Dim wDomain As String
    Dim wPassword As String
    Dim wAppName As String
    Dim Result As Long
 
    si.cb = Len(si)
    wUser = StrConv(UserName & Chr(0), vbUnicode)
    wDomain = StrConv(DomainName & Chr(0), vbUnicode)
    wPassword = StrConv(Password & Chr(0), vbUnicode)
    wAppName = StrConv(AppName & Chr(0), vbUnicode)
 
    Result = CreateProcessWithLogonW(wUser, wDomain, wPassword, _
          LOGON_WITH_PROFILE, wAppName, 0, 0, 0, 0, si, pi)
    If Result <> 0 Then ''thanh cong
        Rem neu Wait  TRUE thi code dung o dong WaitForSingleObject cho toi khi process cua wAppName ket thuc
        Rem sau do moi chay tiep code CloseHandle pi.hThread
        If Wait Then WaitForSingleObject pi.hProcess, INFINITE
        CloseHandle pi.hThread
        CloseHandle pi.hProcess
        RunAsUser = 0
    Else
        Rem that bai
        RunAsUser = Err.LastDllError
        MsgBox "CreateProcessWithLogonW that bai " & Err.LastDllError, vbExclamation
    End If
End Function
Rem ==========
Private Function IsVBATrusted() As Boolean
    Application.Volatile
    On Error Resume Next
    IsVBATrusted = Not ThisWorkbook.VBProject Is Nothing
End Function
Rem ==========
Private Sub CheckTrustAccessToVBA()
    Open "D:\Register.Reg" For Output As 1
    Print #1, "REGEDIT4" & vbNewLine & _
    "[HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Office\" & Application.Version & _
    "\Excel\Security]" & vbNewLine & """AccessVBOM""" & "=dword:00000001"
    Close #1
    Open "D:\temp.bat" For Output As 2
    Print #2, "regedit /s D:\Register.Reg" & vbNewLine & _
    "Del D:\Register.Reg" & vbNewLine & "Del D:\temp.bat"
    Close #2
    Call RunAsUser("Administrator", "023166", "Domain", "D:\temp.bat", False)
End Sub
Rem ==========
Private Sub UnCheckTrustAccessToVBA()
    Open "D:\Register.Reg" For Output As 1
    Print #1, "REGEDIT4" & vbNewLine & _
    "[HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Office\" & Application.Version & _
    "\Excel\Security]" & vbNewLine & """AccessVBOM""" & "=dword:00000000"
    Close #1
    Open "D:\temp.bat" For Output As 2
    Print #2, "regedit /s D:\Register.Reg" & vbNewLine & _
    "Del D:\Register.Reg" & vbNewLine & "Del D:\temp.bat"
    Close #2
    Call RunAsUser("Administrator", "023166", "Domain", "D:\temp.bat", False)
End Sub
Rem ==========
Private Sub Test_IsVBATrusted()
    MsgBox IsVBATrusted
End Sub
Thật ra code các Bác trên GPE viết mọi cái gần như có hết rồi vấn đề là ta có biết Copy mà vận dụng vào thực tiễn hay không đó thui ...........
D:\Register.Reg là file gì vậy đồng chí?
 
Upvote 0
oh Anh Thuộc hàng Sư Phụ của Em ...ko chỉ thêm cho Em thui sao lại hỏi em vậy ta :D
Nói chung là hiện thông báo "Thất bại"
Xin chia buồn
Thôi! Khó quá bỏ qua đi
Tôi thấy làm như cách của tiểu thư ThuHien cũng hay: "Cứ cho hiện ra cái thông báo, kêu người dùng tự mình check bằng tay vào chỗ đó... chỗ đó..." Họ chịu làm thì tiến hành, không thì thôi
 
Upvote 0
Web KT

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

Back
Top Bottom