Làm sao biến chuỗi tham chiếu thành Object thật sự

Liên hệ QC

ndu96081631

Huyền thoại GPE
Thành viên BQT
Super Moderator
Tham gia
5/6/08
Bài viết
30,703
Được thích
53,930
Tôi đang xây dựng hàm thế này:
Mã:
Function ObjectFromRef(byVal szRef as String) as Object
  ......
  Set ObjectFromRef = Hàm gì đó(szRef)
End Function
Ví dụ:
Từ "Picture 1" hoặc "Sheet1!Picture1" ----> Tôi muốn biến chuỗi thành Picture thật sự
Từ "A1" hoặc "Sheet1!A1" ----> Tôi muốn biến chuỗi thành Range thật sự
vân... vân...
Đại khái từ 1 đối số truyền vào dạng chuỗi tôi muốn biến chúng thành object thật sự
Xin hỏi các bạn có cách nào làm được việc này không?
 
Tôi đang xây dựng hàm thế này:
Mã:
Function ObjectFromRef(byVal szRef as String) as Object
  ......
  Set ObjectFromRef = Hàm gì đó(szRef)
End Function
Ví dụ:
Từ "Picture 1" hoặc "Sheet1!Picture1" ----> Tôi muốn biến chuỗi thành Picture thật sự
Từ "A1" hoặc "Sheet1!A1" ----> Tôi muốn biến chuỗi thành Range thật sự
vân... vân...
Đại khái từ 1 đối số truyền vào dạng chuỗi tôi muốn biến chúng thành object thật sự
Xin hỏi các bạn có cách nào làm được việc này không?
Đến thầy mà còn hỏi chắc hiếm có ai biết lắm.
 
Upvote 0
Đến thầy mà còn hỏi chắc hiếm có ai biết lắm.

Đừng nghĩ vậy bạn à! Có những thứ tôi biết mà bạn không biết và ngược lại, chuyện thường!
Ba cây chụm lại nên hòn núi cao huống chi GPE chẳng thiếu nhân tài. Ai cũng "chạy" thì tôi cô đơn lắm bạn à...
 
Upvote 0
Tôi đang xây dựng hàm thế này:
Mã:
Function ObjectFromRef(byVal szRef as String) as Object
  ......
  Set ObjectFromRef = Hàm gì đó(szRef)
End Function
Ví dụ:
Từ "Picture 1" hoặc "Sheet1!Picture1" ----> Tôi muốn biến chuỗi thành Picture thật sự
Từ "A1" hoặc "Sheet1!A1" ----> Tôi muốn biến chuỗi thành Range thật sự
vân... vân...
Đại khái từ 1 đối số truyền vào dạng chuỗi tôi muốn biến chúng thành object thật sự
Xin hỏi các bạn có cách nào làm được việc này không?
Nếu anh dùng VB.Net hoặc một ngôn ngữ nào mới ra đời gần đây thì may ra có. Còn với anh VBA ra đời cách đây hơn 20 năm thì khó mà có vì thời đó khái niệm lập trình hướng đối tượng còn mới sơ khai mà. Tuy nhiên nếu duyệt collections và đối chiều đối từng tên một thì anh cũng tự tạo cho mình một cái "Hàm gì đó(szRef)" gần với cái cần thỏa mãn --=0. Cái này anh chắc anh rõ mà không chịu.
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi đang xây dựng hàm thế này:
Mã:
Function ObjectFromRef(byVal szRef as String) as Object
  ......
  Set ObjectFromRef = Hàm gì đó(szRef)
End Function
Ví dụ:
Từ "Picture 1" hoặc "Sheet1!Picture1" ----> Tôi muốn biến chuỗi thành Picture thật sự
Từ "A1" hoặc "Sheet1!A1" ----> Tôi muốn biến chuỗi thành Range thật sự
vân... vân...
Đại khái từ 1 đối số truyền vào dạng chuỗi tôi muốn biến chúng thành object thật sự
Xin hỏi các bạn có cách nào làm được việc này không?
Theo mình thì với trường hợp của bác xin chia sẻ thế này.
1. Object mà bị đổi tên thì bó tay tất cả trường theo yêu cầu của đầu bài
2. Do việc tạo object và gán object trong VBA khác với cái địa chỉ mà Excel dùng để tham chiếu (Sheet1!A1, Sheet2!Picture1,..) nên ta phải if else rất nhiều (VBA có hơn 100 cái object to nhỏ ^^ danh sách obj thì trên MSDN có rồi).
3. Chia sẻ đoạn code nhỏ dưới đây đã test với trường hợp Range và Picture (các trường hợp còn lại là của bác ^^)
Mã:
Function ObjectFromRef(ByVal szRef As String) As Object
    Dim objRange As Range
    Dim objShape As Shape
    Dim objPic  As Pictures
    Dim myObj As Object
    Dim strCase As String 'Cac truong hop cua Object
    Dim pos As Integer ' Vi tri cua dau !
    strCase = "0"   'Khoi tao chua thuoc loai nao
    pos = 0 'Neu cung object nam tai sheet Active
    pos = InStr(1, szRef, "!")
    'MsgBox "Len: " & Len(szRef) & InStr(1, szRef, "!") + 2 & IsNumeric(Right(szRef, 1)) & IsLetter(Mid(szRef, Len(szRef) - 1, 1))
    If pos = 0 Then 'Neu cung sheet
        'lam tuong tu voi truong hop khac sheet o duoi
    Else
        If Mid(szRef, pos + 1, 1) = "$" Then
            strCase = "1" ' Day chac chan la 1 range
        End If
        If pos + 2 = Len(szRef) And IsNumeric(Right(szRef, 1)) And IsLetter(Mid(szRef, Len(szRef) - 1, 1)) Then
            strCase = "1" ' Truong hop Range la 1 O VD: A1
        End If
        If pos + 2 < Len(szRef) And Mid(szRef, pos + 3, 1) = ":" Then
            strCase = "1" ' Truong hop Range la 1 vung VD: A1:C5
        End If
        If InStrRev("Picture", szRef) Then
            strCase = "2" ' day la picture voi dieu kien khong dc doi Name nhe' neu doi thi y hoc botay voi All truong hop object
        End If
    End If
    MsgBox strCase
    Select Case strCase
            Case "1"
                Set ObjectFromRef = Range(szRef)
            Case "2"
                Set ObjectFromRef = objPic
            Case Else
                Set ObjectFromRef = myObj
    End Select
End Function
Sub TestObj()
    MsgBox "Day la: " & ObjectFromRef("Sheet1!A1:C5").Count
End Sub
Function IsLetter(strValue As String) As Boolean
    Dim intPos As Integer
    For intPos = 1 To Len(strValue)
        Select Case Asc(Mid(strValue, intPos, 1))
            Case 65 To 90, 97 To 122
                IsLetter = True
            Case Else
                IsLetter = False
                Exit For
        End Select
    Next
End Function
Trên đây chỉ là chút ý kiến đóng góp mang tính chất tham khảo thôi nha (vì tôi mới bắt đầu tìm hiểu VBA đc 1 tuần thôi @@)
 
Lần chỉnh sửa cuối:
Upvote 0
Theo mình thì với trường hợp của bác xin chia sẻ thế này.
1. Object mà bị đổi tên thì bó tay tất cả trường theo yêu cầu của đầu bài
2. Do việc tạo object và gán object trong VBA khác với cái địa chỉ mà Excel dùng để tham chiếu (Sheet1!A1, Sheet2!Picture1,..) nên ta phải if else rất nhiều (VBA có hơn 100 cái object to nhỏ ^^ danh sách obj thì trên MSDN có rồi).
3. Chia sẻ đoạn code nhỏ dưới đây đã test với trường hợp Range và Picture (các trường hợp còn lại là của bác ^^)
Vâng! Thì tôi cũng đang làm theo cách này: Tách chuỗi thành 2 phần dựa theo ký tự "!" để lấy tên Sheet và tên Object, tuy nhiên tôi cảm thấy cách này không hay và thiếu tính chính xác
Dù sao cũng cảm ơn bạn và mọi người!
 
Upvote 0
Vâng! Thì tôi cũng đang làm theo cách này: Tách chuỗi thành 2 phần dựa theo ký tự "!" để lấy tên Sheet và tên Object, tuy nhiên tôi cảm thấy cách này không hay và thiếu tính chính xác
Dù sao cũng cảm ơn bạn và mọi người!
Theo tui thì cách if else là giải pháp duy nhất cho yêu cầu của đề bài rồi, h quan trọng cách là nhận diện được các trường hợp thôi. Bài toán này không có đáp án chính xác 100% vì với trường hợp object bị đổi tên thì chắc Billgate cũng botay thôi (ví dụ cái Picture1 hoặc Range bác đặt name thành myABC thì không thể nhận diện được tham chiếu str truyền vào).
Trong Tin học có 1 giải thuật gọi tên là Tham Lam (Greedy Algorithm) mà các em đi thi học sinh giỏi hay sử dụng khi biết chắc rằng không có lời giải tối ưu (hoặc nếu làm đc tối ưu thì thời gian ko cho phép) vì thế họ đã sinh ra tập hợp các kết quả mà họ đoán nó sẽ giống hoặc gần giống với bộ test của Ban giám khảo (để ít nhất khi Giám khảo chấm họ đều ăn điểm đã), sau khi làm xong bước này nếu còn thời gian họ mới tham lam thêm bằng các đáp án mới có liên quan đến 1 trong các đáp án đã sinh ra (gọi là biến thể) để hi vọng trùng với đáp án trong bộ test của Giám khảo (tiếp tục ghi điểm).
Đây chỉ là chia sẽ kinh nghiệm mang tính cá nhân khi vận dungj giải thuật Tham Lam để để giải quyết các công việc thực tế ở cơ quan. Do mới tìm hiểu VBA mong nhận được sự giúp đỡ của các Thầy, các bậc tiền bối của GPE trong thời gian tới.
 
Upvote 0
Web KT
Back
Top Bottom