Find column-Tìm cột theo số

tuhocvba

Administrator
Thành viên BQT
Chúng ta có bài toán như sau:
Người dùng nhập tên cột là "A" hoặc "AA", chúng ta mong muốn nhận được tên cột theo số là 1 hoặc 27.
Mã:
'INPUT: ex: AA
'OUTPUT: chi ra cot bang so
'Neu ham co gia tri = 0 tuc la dang bi loi, dia chi cot nhap sai.
Function timdiachicot(ByVal s As String) As Integer
    Dim i As Integer
    On Error Resume Next
    timdiachicot = 0
    i = Range(s & "1").Column
    timdiachicot = i
End Function
Sub test()
    MsgBox timdiachicot("AA")
End Sub
Kết quả:
Bạn cần đăng nhập để thấy hình ảnh

Hàm timdiachicot có giá trị trả về là 0 nếu người dùng nhập tên cột sai. Ví dụ người dùng nhập vào là "XFDBB" thì hàm sẽ trả về là 0.
Vì lý do ấy, cho nên trong hàm sử dụng On Error Resume Next, tức là phớt lờ lỗi, nếu xảy ra lỗi. Tuy nhiên chúng ta không cần lo lắng, vì trong trường hợp này, chúng ta hoàn toàn kiểm soát được lỗi.
Bây giờ nếu tôi cố tình tạo ra lỗi ở trên thủ tục test, chương trình vẫn báo lỗi bình thường. Cụ thể tôi sửa lại code cho thủ tục test như sau:
Mã:
Sub test()

    Dim s2 As String
    s2 = "XFDAA1"
    MsgBox timdiachicot("AA")
    Msgbox Range(s2).Column
End Sub
Kết quả:
Bạn cần đăng nhập để thấy hình ảnh

Video thuyết minh:
Bạn cần đăng nhập để thấy đa phương tiện
 

giaiphapvba

Administrator
Thành viên BQT
Đúng là cách trên giải quyết được triệt để vấn đề.
Ban đầu khi đọc đề bài, em nghĩ tới mã Asscii.
Em suy nghĩ ngược lại, là từ số cột number, đi ngược lại, tìm tên cột "A" hay "B". Nếu như thế thì có code:
Mã:
Sub Sample1()
    Dim num As Long
    num = InputBox("Nhap so cot. Ex:1")
    MsgBox Chr(num + 64)
End Sub
Bởi vì mã asscii của "A" là 65 cho nên em nghĩ tới chương trình như trên.
Tuy nhiên cái này chỉ đúng với tên cột từ "A" tới "Z". Nếu tên cột là hai ký tự như "AA" thì không xử lý được nữa.
Trong trường hợp này em nghĩ sử dụng thuộc tính Address.
Mã:
MsgBox Cells(1, 27).Address
Kết quả được như dưới đây:
Bạn cần đăng nhập để thấy hình ảnh

Kết quả trả về là [$AA$1], đây là các tham số của thuộc tính Address trong đó lần lượt là cột, dòng, và các tham số tham chiếu tuyệt đối và tương đối.
Em thay đổi code một chút:
Mã:
MsgBox Cells(1, 27).Address(True, False)
Kết quả là:
Bạn cần đăng nhập để thấy hình ảnh

Kết quả [AA$1] cho thấy chỉ có dòng là được tham chiếu tuyệt đối.
Em thử với code sau:
Mã:
Sub Sample2()
    Dim num As Long, buf As String
    num = InputBox("Nhap so cot. Ex: 27")
    buf = Cells(1, num).Address(True, False)
    buf = Left(buf, InStr(buf, "$") - 1)
    MsgBox buf
End Sub
Em nhập vào 27 và được kết quả là AA như các ảnh dưới đây:
Bạn cần đăng nhập để thấy hình ảnh

Bạn cần đăng nhập để thấy hình ảnh

Để không phải xử lý dấu đô la $, em bỏ hết tham số tuyệt đối:
Mã:
Sub Sample3()
    Dim num As Long, buf As String
    num = InputBox("Nhap so cot. Ex: 27")
    buf = Cells(1, num).Address(False, False) 'bỏ tham số tuyệt đối, để là False hết. Kết quả sẽ cho ra có dạng AA1
    buf = Left(buf, Len(buf) - 1) 'Bỏ số 1 ở cuối đi
    MsgBox buf
End Sub
Nguồn tham khảo:
 

vbano1

SMod
Thành viên BQT
Như câu chuyện đã trình bày .
Thì code của cần cải thiện là:
Mã:
'A => 1
'B => 2
'...
'AB => 28
Function timdiachicot(ByVal s As String) As Integer
    Dim i As Integer
    On Error Resume Next
    timdiachicot = 0
    i = ThisWorkbook.Sheets(1).Range(s & "1").Column
    timdiachicot = i
End Function
 

tuhocvba

Administrator
Thành viên BQT
Bài , thì ngược lại từ số thành cột sẽ là:
Mã:
'27 => AA
'1  => A
Function fromNUmberToString(ByVal num As Integer) As String
    Dim buf As String
    On Error Resume Next
 
    buf = ThisWorkbook.Sheets(1).Cells(1, num).Address(False, False)
    buf = Left(buf, Len(buf) - 1)
    fromNUmberToString = buf
End Function
 
Top