Hỏi đáp về VBA (các vấn đề căn bản nhất)

Liên hệ QC

havietchuong

Thành viên tiêu biểu
Tham gia
16/6/09
Bài viết
490
Được thích
570
Giới tính
Nam
Nghề nghiệp
Giáo viên tiểu học.
Tôi không biết đặt đặt câu hỏi này nơi nào cho đúng, xin gởi vào đây. Nếu có sai xin thông cảm cho người mới học VBA.
Trong 1 cửa sổ Module có thể ghi nhiều nhiều Macro và mỗi macro có thể ứng với 1 tổ hợp phím nào đó được không?
Tôi thử nhiều lần thì khi được khi không. Không biết nó thế nào? Trong tập tin sau có lỗi gì không trong cách ghi Macro? Cám ơn.
 

File đính kèm

  • baitap1.xls
    28 KB · Đọc: 244
Lần chỉnh sửa cuối:
Không phải cận trên và cận dưới, mà là chỉ số trên và chỉ số dưới. Trong toán học và lập trình phải phát biểu cho chính xác.

Nếu Sư phụ giỏi hơn người viết cuốn sách lập trình căn bản này (file pdf) thì hãy sửa lưng người khác Sư phụ nhé!

http://www.giaiphapexcel.com/forum/...ung-kiến-thức-căn-bản-VBA&p=539115#post539115


Trích tại trang 11:

Xác định cận của mảng:
Các hàm Ubound và LBound có thể tìm cận trên và dưới của một mảng.
Cú pháp:
x = UBound(arrayname)
UBound trả lại chỉ số cao nhất của mảng. Số phần tử thật sự của mảng phụ thuộc vào
điểm bắt đầu của mảng. Nếu dùng cận dưới mặc định của mảng là 0, Ubound nhỏ hơn
số phần tử 1.
iArraySize = UBound(array) + 1
Tuy nhiên, công thức chính xác là:
iArraySize = UBound(array) – LBound(array) + 1

Các bạn mới học lập trình cũng nên tải sách này về (tại link trên) để tham khảo một cách cơ bản về lập trình!
 
Lần chỉnh sửa cuối:
Upvote 0
Nếu Sư phụ giỏi hơn người viết cuốn sách lập trình căn bản này (file pdf) thì hãy sửa lưng người khác Sư phụ nhé!

Tôi không giỏi hơn ai, cũng không sửa lưng. Tôi phát biểu vì tôi thấy là sai. Ai thấy tôi sai thì tranh luận.

Cận theo tiếng Hán Việt là "gần". Gần trên và gần dười thường dùng trong việc tìm kiếm không chính xác, cũng như dò tìm trong phép nội suy.
 
Upvote 0
Không phải cận trên và cận dưới, mà là chỉ số trên và chỉ số dưới. Trong toán học và lập trình phải phát biểu cho chính xác.

1) Thật sự mà nói là tôi nói theo sách nói chứ không phải tôi tự chế ra mà nói.

2) Bound theo tôi nghĩ nó là biên giới, vậy theo tôi nói, Hàm Ubound để xác định BIÊN TRÊN và Lbound để xác định BIÊN DƯỚI. Vậy có ai bàn gì về cái tôi nói hay không?
 
Upvote 0
1) Thật sự mà nói là tôi nói theo sách nói chứ không phải tôi tự chế ra mà nói.

2) Bound theo tôi nghĩ nó là biên giới, vậy theo tôi nói, Hàm Ubound để xác định BIÊN TRÊN và Lbound để xác định BIÊN DƯỚI. Vậy có ai bàn gì về cái tôi nói hay không?

Biên trên và biên dưới thì đúng. Chỉ khi dùng cận mới sai. Cận là "gần"

Tôi phải nhắc lại bao nhiêu lần rằng hãy chỉ ra chỗ sai của tôi, chứ đừng cãi ngang mà không đọc?
 
Lần chỉnh sửa cuối:
Upvote 0
Em cảm ơn anh nhiều ạ! Anh Nghĩa cho em hỏi ngoài hàm Ubound có thể thay bằng hàm nào khác không ạ?

Khi bạn thao tác trên một mảng được truyền vào dưới dạng tham số chẳng hạn thì nhiều khi bạn không biết được chỉ số dưới/trên của chiều nhất định là thế nào. Tại sao? Vì người dùng có thể truyền mảng được trả về bởi một hàm nào đó. Thậm chí những hàm có sẵn cũng trả về mảng mà chỉ số dưới không nhất quán: vd. hàm Split trả về mảng mà chỉ số dưới luôn là 0, hàm Array trả về mảng mà chỉ số dưới là 0 nếu không có Option Base hoặc có Option Base 0, còn nếu có Option Base 1 thì mảng trả về có chỉ số dưới là 1. Ngoài ra một hàm tự tạo bất kỳ cũng có thể trả về một mảng. Mà lúc đó thì chả có qui luật gì cả. Vd. người ta có thể trả về mảng mà chỉ số dưới là 5, -3, 10 ...

Bạn có thói quen trả về mảng có chỉ số dưới là 1 (0)? Nhưng không có nghĩa là không có vị nào trả về mảng có chỉ số dưới <> 0, 1.

Ví dụ code
Mã:
Sub he()
Dim a, arr(4 To 8, 3 To 5)
    a = Array(3, 4, 5)
    MsgBox a(0)
    MsgBox LBound(arr, 1)   '   = 4
End Sub

Nếu không có Option Base hoặc có Option Base 0 thì code chạy "ngon". Nhưng nếu có Option Base 1 thì sẽ có lỗi "Subscript out of range" vì mảng trả về bởi hàm Array có chỉ số dưới là 1. Truy cập tới phần tử có chỉ số 0 thì rõ ràng có lỗi rồi.

Trong ví dụ trên thì rõ ràng mảng arr có chỉ số dưới của chiều thứ nhất là 4, không phụ thuộc vào Option Base. Tất nhiên truy cập tới vd. Arr(1, 4) là có lỗi vì chỉ số của chiều thứ nhất chỉ có thể là 4, 5, 6, 7 hoặc 8. Nói nôm na thì mảng có 5 dòng và 3 cột nhưng các dòng có chỉ số là 4, 5, 6, 7 hoặc 8, còn các cột có chỉ số là 3, 4 hoặc 5.

Vì chỉ số dưới và trên có thể bất kỳ - không chắc chắn là 0, 1 hay giá trị nào đó - nên khi thao tác trên mảng thì an toàn nhất là dùng LBound và UBound.
Vd.
Mã:
    For r = LBound(arr) To UBound(arr)
        For c = LBound(arr, 2) To UBound(arr, 2)
            ...
        Next
    Next

Chỉ khi ta biết chắc chắn chỉ số dưới là thế nào thì có thể không dùng LBound.
Vd. nếu ta có
Mã:
Sub he()
Dim arr
    arr = Range("D12:F24")
    ...
End Sub

Thì chỉ số dưới của 2 chiều đều là 1

Theo tôi nghĩ thì trong VBA không có hàm nào ngoài L/UBound. Vì các hàm này là quá đơn giản rồi. Dù có thêm hàm nào chăng nữa thì nó cũng phải có ít nhất 2 đối số: mảng để biết trả về kết quả cho mảng cụ thể nào, và chiều để biết trả về cho chiều nào. Vậy thì tại sao lại phải đẻ thêm 1 hàm khác? Và bạn muốn có hàm khác để làm gì?
 
Upvote 0
Biên trên và biên dưới thì đúng. Chỉ khi dùng cận mới sai. Cận là "gần"

Tôi phải nhắc lại bao nhiêu lần rằng hãy chỉ ra chỗ sai của tôi, chứ đừng cãi ngang mà không đọc?
Vậy phát biểu không chính xác thì Thầy siwtom cũng phát biểu sai hay sao?

Không đúng. Tôi nhìn thấy là các chuỗi được phân cách bởi 2 ký tự là ";" và " ". Đối với bạn có thể " " chả là gì cả nhưng bạn hãy tin rằng ký tự dấu cách " " là ký tự "ngag hàng" với tất cả các ký tự khác.



Một ví dụ

Module
Mã:
Public Sub QuickSort1DArray(Arr, iLo As Long, iHi As Long, ByVal sortAtoZ As Boolean)
'    Arr là mảng cần sắp xếp
'    sortAtoZ xác định cách sắp xếp tăng hay giảm
[COLOR=#ff0000][B]'    iLo là cận dưới của mảng Arr, iHi là cận trên của mảng Arr[/B][/COLOR]

Dim Lo As Long, Hi As Long, iMid, DoChange As Boolean, s

    Do
        Lo = iLo
        Hi = iHi
        
        iMid = Arr((Lo + Hi) \ 2)
        Do
            If sortAtoZ Then
                Do While Arr(Lo) < iMid
                    Lo = Lo + 1
                Loop
                Do While Arr(Hi) > iMid
                    Hi = Hi - 1
                Loop
            Else
                Do While Arr(Lo) > iMid
                    Lo = Lo + 1
                Loop
                Do While Arr(Hi) < iMid
                    Hi = Hi - 1
                Loop
            End If
            
            If Lo <= Hi Then
                If sortAtoZ Then
                    DoChange = (Arr(Lo) > Arr(Hi))
                Else
                    DoChange = (Arr(Lo) < Arr(Hi))
                End If
                If DoChange Then
                    s = Arr(Lo)
                    Arr(Lo) = Arr(Hi)
                    Arr(Hi) = s
                End If
                
                Lo = Lo + 1
                Hi = Hi - 1
            End If
        Loop Until Lo > Hi
        If Hi > iLo Then QuickSort1DArray Arr, iLo, Hi, sortAtoZ
        iLo = Lo
    Loop Until Lo >= iHi
End Sub

Sub Button1_Click()
Dim s As String, k As Long, Arr, result() As String
    ReDim result(1 To [B][COLOR=#ff0000]4[/COLOR][/B], 1 To 1)
    
    For k = 1 To[B][COLOR=#ff0000] 4[/COLOR][/B]
        s = Cells(k, 1).Value
        Arr = Split(s, "; ")
        QuickSort1DArray Arr, LBound(Arr), UBound(Arr), True
        result(k, 1) = Join(Arr, "; ")
    Next
    
    Range("B1").Resize(UBound(result)).Value = result
End Sub

Nếu số dòng khác đi thì sửa chố đỏ đỏ
http://www.giaiphapexcel.com/forum/showthread.php?86365-Hỏi-về-cách-sort-array&p=538522#post538522
 
Upvote 0

Tôi cũng thấy là nên dùng "chỉ số" thay cận. Dùng cận cũng được, do nhiều khi ta dùng cách nói "bình dân", nhưng dùng "chỉ số" là chính xác.
------------
Nếu tôi không lầm thì trong Toán học khái niệm cận cũng có thể hiểu là "giới hạn". Ví dụ ta có tập vô hạn các số tăng dần (chuỗi số) có giới hạn là g. g là số nhỏ nhất trong tập số thực mà > tất cả các số của tập (chuỗi) kia. Nói cách khác thì g không thuộc tập kia. Nhưng L/UBound thì "chắc chắn" thuộc "tập các chỉ số" của mảng. Vậy có thể chấp nhận rằng: dùng cận là không chính xác.
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi cũng thấy là nên dùng "chỉ số" thay cận. Dùng cận cũng được, do nhiều khi ta dùng cách nói "bình dân", nhưng dùng "chỉ số" là chính xác.
Chỉ số là Index, Bound là Biên, vậy dùng đúng là biên chứ không phải là chỉ số, theo em là vậy!

LBound có nghĩa là Low Bound và UBound có nghĩa là Up Bound vậy phải là Biên Dưới và Biên Trên chứ không thể nói là Chỉ số Trên, Chỉ số dưới.
 
Lần chỉnh sửa cuối:
Upvote 0
Nếu tôi không lầm thì trong Toán học khái niệm cận cũng có thể hiểu là "giới hạn". Ví dụ ta có tập vô hạn các số tăng dần (chuỗi số) có giới hạn là g. g là số nhỏ nhất trong tập số thực mà > tất cả các số của tập (chuỗi) kia. Nói cách khác thì g không thuộc tập kia. Nhưng L/UBound thì "chắc chắn" thuộc "tập các chỉ số" của mảng. Vậy có thể chấp nhận rằng: dùng cận là không chính xác.

Ở đây phải phân biệt rõ ràng, nếu nó CẬN là chưa chính xác thì CHỈ SỐ cũng không chính xác, bởi, CHỈ SỐ từ 0 đến 10 thì mỗi giá trị là một chỉ số, còn 0 và 10 mới chính là số biên, không thể thay thế số biên ở giữa được, nhưng nói chỉ số 2 đến chỉ số 9 trong tập 0 đến 10 đều được. Vậy thì dùng CHỈ SỐ LÀ KHÔNG HỢP LÝ.

Cho nên phải gọi LBOUND hay UBOUND là hàm xác định SỐ BIÊN DƯỚI & SỐ BIÊN TRÊN của một mảng là hoàn toàn chính xác.
 
Upvote 0
Chỉ số là Index, Bound là Biên, vậy dùng đúng là biên chứ không phải là chỉ số, theo em là vậy!

LBound có nghĩa là Low Bound và UBound có nghĩa là Up Bound vậy phải là Biên Dưới và Biên Trên chứ không thể nói là Chỉ số Trên, Chỉ số dưới.

Người ta dùng chỉ số vì như anh siwtom nói, LBound và UBound thuộc về 1 tập hợp các chỉ số. Nghĩa là có chỉ số trên, chỉ số dưới, và chỉ số giữa giữa. Còn biên thì chỉ có ở 2 đầu.

Nếu dùng biên thì không sai, nhưng khi truy xuất phần tử thứ n, thì n vẫn sẽ được gọi là chỉ số: Số chỉ ra vị trí của phần tử. Nếu số n chỉ ra vị trí biên dưới thì n là LBound, nếu số n chỉ ra vị trí biên trên, thì n là UBound

Vậy dùng chung "chỉ số" cho khỏe.

Ghi chú: L viết tắt của Lower và U viết tắt của Upper, chứ không phải Low và Up
 
Upvote 0
Chỉ số là Index, Bound là Biên, vậy dùng đúng là biên chứ không phải là chỉ số, theo em là vậy!

LBound có nghĩa là Low Bound và UBound có nghĩa là Up Bound vậy phải là Biên Dưới và Biên Trên chứ không thể nói là Chỉ số Trên, Chỉ số dưới.

Thì cái "biên" đấy nó là một "chỉ số" chứ còn là gì nữa? Những mỗi chiều trong mảng có những chỉ số. Trong tất cả những chỉ số đó thì chỉ số lớn nhất ta gọi là U còn nhỏ nhất ta gọi là L. Thế thôi.

Vậy thì bạn dùng "biên" hay "chỉ số" thì tôi thấy được vì "chỉ số" hay "biên" đó thuộc "tập các chỉ số trong chiều nào đó".

Tôi đã nói rồi. Tôi nói kiểu "bình dân" (tức không phải đang giảng trên giảng đường) là "cận" nhưng bản thân tôi nếu phải chọn chính xác thì tôi sẽ chọn "chỉ số". Cái biên trên/dưới thì nó cũng là chỉ số chứ nó là cái gì khác?
 
Upvote 0
Người ta dùng chỉ số vì như anh siwtom nói, LBound và UBound thuộc về 1 tập hợp các chỉ số. Nghĩa là có chỉ số trên, chỉ số dưới, và chỉ số giữa giữa. Còn biên thì chỉ có ở 2 đầu.

Nếu dùng biên thì không sai, nhưng khi truy xuất phần tử thứ n, thì n vẫn sẽ được gọi là chỉ số: Số chỉ ra vị trí của phần tử. Nếu số n chỉ ra vị trí biên dưới thì n là LBound, nếu số n chỉ ra vị trí biên trên, thì n là UBound

Vậy dùng chung "chỉ số" cho khỏe.

Ghi chú: L viết tắt của Lower và U viết tắt của Upper, chứ không phải Low và Up
Khi đã phát biểu cái gọi là chính xác thì phải triệt để chính xác, chứ bảo người ta phát biểu không chính xác mà lại dùng chung chung như thế thì không nên.

Thì cái "biên" đấy nó là một "chỉ số" chứ còn là gì nữa? Những mỗi chiều trong mảng có những chỉ số. Trong tất cả những chỉ số đó thì chỉ số lớn nhất ta gọi là U còn nhỏ nhất ta gọi là L. Thế thôi.

Vậy thì bạn dùng "biên" hay "chỉ số" thì tôi thấy được vì "chỉ số" hay "biên" đó thuộc "tập các chỉ số trong chiều nào đó".

Tôi đã nói rồi. Tôi nói kiểu "bình dân" (tức không phải đang giảng trên giảng đường) là "cận" nhưng bản thân tôi nếu phải chọn chính xác thì tôi sẽ chọn "chỉ số". Cái biên trên/dưới thì nó cũng là chỉ số chứ nó là cái gì khác?

Cách gọi và thói quen cũng như thông lệ của chúng ta như thế nào thì thôi, cứ để như vậy, còn chỉnh sửa thì phải chỉnh sửa cho chính xác Thầy ạ.

Phải hiểu rõ chữ Anh: Index khác với Bound. Và đã dịch thì phải dịch cho chính xác, còn không thì ta về ta tắm ao ta, miễn sao ta hiểu ta là được.
 
Lần chỉnh sửa cuối:
Upvote 0
Ở đây phải phân biệt rõ ràng, nếu nó CẬN là chưa chính xác thì CHỈ SỐ cũng không chính xác, bởi, CHỈ SỐ từ 0 đến 10 thì mỗi giá trị là một chỉ số, còn 0 và 10 mới chính là số biên, không thể thay thế số biên ở giữa được, nhưng nói chỉ số 2 đến chỉ số 9 trong tập 0 đến 10 đều được. Vậy thì dùng CHỈ SỐ LÀ KHÔNG HỢP LÝ.

Cho nên phải gọi LBOUND hay UBOUND là hàm xác định SỐ BIÊN DƯỚI & SỐ BIÊN TRÊN của một mảng là hoàn toàn chính xác.

Tôi không nói là vd. UBound là "chỉ số". Tôi nói là: UBound là "chỉ số trên"
Bạn có thấy khác không?
------------
Ngoài ra bạn gọi tên tôi trong bài # 254 nên tôi buộc phải trả lời bạn. Chứ tôi không góp ý gì cho bạn cả.
 
Upvote 0
Khi đã phát biểu cái gọi là chính xác thì phải triệt để chính xác, chứ bảo người ta phát biểu không chính xác mà lại dùng chung chung như thế thì không nên.

Chỗ cụ thể này dùng chung là chính xác. Từ 0 đến 10, gọi chung là chỉ số, vì đều chỉ ra vị trí của phần tử trong 1 chiều nào đó của mảng.

Chỉ số nhỏ nhất và chỉ số lớn nhất chỉ là trường hợp đặc biệt (chạm biên) của chỉ số má thôi.

Bắt đầu vặn lại (tranh luận) đây, nhưng vặn chưa đúng chỗ.
 
Upvote 0
Tôi không nói là vd. UBound là "chỉ số". Tôi nói là: UBound là "chỉ số trên"
Bạn có thấy khác không?
------------
Ngoài ra bạn gọi tên tôi trong bài # 254 nên tôi buộc phải trả lời bạn. Chứ tôi không góp ý gì cho bạn cả.
Em có 1 đến 10, vậy chỉ số trên 1 là 2 được không? Nhưng nói Biên số trên 1 là 2 có được không?

Nếu mà được vậy thì ngôn ngữ lập trình người ta đã dùng LIndex và UIndex rồi chứ không ai lại dùng Lbound hay UBound cả!
 
Lần chỉnh sửa cuối:
Upvote 0
Em có 1 đến 10, vậy chỉ số trên 1 là 2 được không? Nhưng nói Biên số trên 1 là 2 có được không?

Nếu mà được vậy thì ngôn ngữ lập trình người ta đã dùng LIndex và UIndex rồi chứ không ai lại dùng Lbound hay UBound cả!

Tôi đã nói rồi. Do bạn gọi tên tôi trong bài # 254 nên tôi buộc phải trả lời bạn, và nói về quan điểm của mình. Chỉ thế thôi. Bạn có quan điểm khác thì bạn cứ trình bầy. Có chỗ nào tôi chỉ trích bạn đâu?

Đơn giản vì tôi không muốn góp ý gì cho bạn cả.
 
Upvote 0
Khi đã phát biểu cái gọi là chính xác thì phải triệt để chính xác, chứ bảo người ta phát biểu không chính xác mà lại dùng chung chung như thế thì không nên.

Đọc bài 262

Và đã dịch thì phải dịch cho chính xác

Đọc câu cuối bài 258:
Ghi chú: L viết tắt của Lower và U viết tắt của Upper, chứ không phải Low và Up
 
Upvote 0
Đọc bài 262



Đọc câu cuối bài 258:
Ghi chú: L viết tắt của Lower và U viết tắt của Upper, chứ không phải Low và Up
Theo Help:

UBound Function: Returns a Long containing the largest available subscript for the indicated dimension of an array.


LBound Function: Returns a Long containing the smallest available subscript for the indicated dimension of an array.

Vậy đi, khi dùng CHỈ SỐ thì phải gọi CHỈ SỐ LỚN NHẤT và CHỈ SỐ NHỎ NHẤT chứ không trên hay dưới.

Khi dùng BIÊN, vì biên là giá trị xác định (giống như mạo từ xác định vậy) ở mỗi 2 đầu kích thước chỉ định của một mảng, vì thế, chỉ cần nói BIÊN TRÊN hoặc BIÊN DƯỚI là OK (vì đã là biên là chỉ số duy nhất ở 2 đầu).
 
Upvote 0
Theo Help:

UBound Function: Returns a Long containing the largest available subscript for the indicated dimension of an array.

LBound Function: Returns a Long containing the smallest available subscript for the indicated dimension of an array.

Vậy đi, khi dùng CHỈ SỐ thì phải gọi CHỈ SỐ LỚN NHẤT và CHỈ SỐ NHỎ NHẤT chứ không trên hay dưới.

Khi dùng BIÊN, vì biên là giá trị xác định (giống như mạo từ xác định vậy) ở mỗi 2 đầu kích thước chỉ định của một mảng, vì thế, chỉ cần nói BIÊN TRÊN hoặc BIÊN DƯỚI là OK (vì đã là biên là chỉ số duy nhất ở 2 đầu).

Ý kiến thôi chứ không có ý tranh luận.

1. Tôi xem từ điển Anh - Ba Lan (sách từ điển) thì thấy nghĩa của subscript là indeks (tiếng Anh là index, tiếng Việt là chỉ số)

2. Tôi xem wiktionary Việt thì thấy nghĩa của subscript là "chỉ số dưới"
http://vi.wiktionary.org/wiki/subscript

3. Tôi xem wiktionary Anh thì thấy nghĩa của subscript (nghĩa thứ hai) là "A numerical index into an array"
http://en.wiktionary.org/wiki/subscript

4. Từ điển Hồ Ngọc Đức tất nhiên sẽ dịch là "chỉ số dưới".
View attachment 115878

Nếu dịch subscript là "chỉ số" là sai thì chả nhẽ có nhiều người sai thế.

Nghĩa của subscript là thế thì phải chấp nhận thôi.

L/UBound chẳng qua cũng là chỉ số (chỉ số "đặc biệt"), hiển nhiên như câu: "Số nguyên tố là số tự nhiên. Số hữu tỷ là số thực".
------------
Ngoài ta nếu bạn đọc kỹ các bài thì thấy không ai "đeo bám" cái "biên" của bạn cả.
Tôi viết:
Vậy thì bạn dùng "biên" hay "chỉ số" thì tôi thấy được

Anh ptm0412 viết
Nếu dùng biên thì không sai

Mà bạn cứ tưởng tượng dimension nó là một cái gì đó có "điểm bắt đầu - điểm dưới" và "điểm kết thúc - điểm cuối - điểm trên" thì bạn thấy thoải mái ngay mà.
 
Lần chỉnh sửa cuối:
Upvote 0
L/UBound chẳng qua cũng là chỉ số (chỉ số "đặc biệt"), hiển nhiên như câu: "Số nguyên tố là số tự nhiên. Số hữu tỷ là số thực".
------------
Anh siwtom ạ, tôi cũng nói như thế: "Chỉ số nhỏ nhất và chỉ số lớn nhất chỉ là trường hợp đặc biệt (chạm biên) của chỉ số mà thôi."

Cơ mà "đối tác" không đọc, hoặc đọc không hiểu, hoặc cố tình không hiểu, hoặc không biết thế nào là tổng quát mí lị chi tiết, thì thôi anh ạ.

Vì nếu phản biện, thì phải chứng minh ngược lại: UBound và LBound không phải chỉ số, nghĩa là chứng minh 2 giá trị đó không dùng để chỉ ra vị trí.
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT
Back
Top Bottom