Có cách nào lấy địa chỉ o từ công thức

Liên hệ QC

thuyyeu99

Trùm Nhiều Chuyện
Tham gia
6/6/08
Bài viết
1,729
Được thích
875
Trong VBA mình có cách nào lấy địa chỉ ô từ công thức không ạh

Em ví dụ: em có 1 cái TextBox có giá trị là =A1+A2. có cách nào mình tách riêng từng Range địa chỉ được không ạh

kết quả A1 ----------- A2
 
Trong VBA mình có cách nào lấy địa chỉ ô từ công thức không ạh

Em ví dụ: em có 1 cái TextBox có giá trị là =A1+A2. có cách nào mình tách riêng từng Range địa chỉ được không ạh

kết quả A1 ----------- A2
Khó hiểu quá bạn à, hiểu chết liền đó.
Nếu là text thì dùng các hàm tách left, right, mid... được không?
 
Upvote 0
rủi địa chỉ có dạng A1:A2,$A1:$A2,$A$1:$A$2,A$1:A$2. còn +,-,x,:, nữa rủi trong ô A3 của em có công thức là 19+20 nói chung nó nhiều trường hợp quá em không nghĩ ra cách gì để lấy được (Ý em là em muốn suy từ công thức đó gồm những địa chỉ của ô nà) Ví dụ tại A1 “=Sum(A2:A3)” lấy ra A2 và A3 hay A2:A3 cũng được
A1 “= $A$2+$A$3” lấy ra $A$2 và $A$3
 
Upvote 0
rủi địa chỉ có dạng A1:A2,$A1:$A2,$A$1:$A$2,A$1:A$2. còn +,-,x,:, nữa rủi trong ô A3 của em có công thức là 19+20 nói chung nó nhiều trường hợp quá em không nghĩ ra cách gì để lấy được (Ý em là em muốn suy từ công thức đó gồm những địa chỉ của ô nà) Ví dụ tại A1 “=Sum(A2:A3)” lấy ra A2 và A3 hay A2:A3 cũng được
A1 “= $A$2+$A$3” lấy ra $A$2 và $A$3
Cái này hơi rộng, nên xét theo A1:A2,$A1:$A2,$A$1:$A$2,A$1:A$2 trước, ie theo dấu "," dùng Split tách ra.
Phần này làm tiếp sau A1 “= $A$2+$A$3” chắc là cắn cứ theo địa chỉ cột A, B, ... lập thành một array và tách tiếp.
Từ từ nghiên cứu thử.
 
Upvote 0
Ớ vấn đê này em có 1 câu hỏi:
Vậy có cách nào phân biệt đươc hai loại Formula này không
=D5+E5*(E8/E6-E7)
=SUM(D1:D4)
Một cái là công thức cộng bình thường, một cái là dùng Function. Vậy làm sao để phân biệt chúng trên VBA?
Trường hợp này sẽ không khả thi nếu hàm được lồng vào nhau quá nhiều.
Ví dụ:
=IF(.. Sum(...)*Sumproduct(...)+sum(...)...IF(...))+G80/J120
Xem ra không dễ ăn với câu hỏi của bạn rồi!;;;;;;;;;;;
Thân.
 
Lần chỉnh sửa cuối:
Upvote 0
hihihi! Cuối cùng cũng ra lò 1 code cùi bắp.
Mã:
Sub chay()
On Error GoTo Loi
Dim k  As String, cel As Range
Set cel = Application.InputBox("Chon cells chua cong thuc:", Type:=8)
k = cel.Formula
k = Replace(k, "=", " ")
k = Replace(k, "^", " ")
k = Replace(k, "*", " ")
k = Replace(k, "/", " ")
k = Replace(k, "+", " ")
k = Replace(k, "-", " ")
k = Replace(k, ">", " ")
k = Replace(k, "<", " ")
For i = 1 To Len(k)
    If Mid(k, i, 1) <> " " And Mid(k, i, 1) <> "," Then
    If WorksheetFunction.IsText(Mid(k, i, 1)) And IsNumeric(Mid(k, i + 1, 1)) Then            'A1
        Temp = Temp & Mid(k, i, 2) & " "
        i = i + 1
    ElseIf Mid(k, i, 1) = "$" And WorksheetFunction.IsText(Mid(k, i + 1, 1)) And IsNumeric(Mid(k, i + 2, 1)) Then    '$A1
        Temp = Temp & Mid(k, i, 3) & " "
        i = i + 2
    ElseIf WorksheetFunction.IsText(Mid(k, i, 1)) And Mid(k, i + 1, 1) = "$" And IsNumeric(Mid(k, i + 2, 1)) Then     'A$1
        Temp = Temp & Mid(k, i, 3) & " "
        i = i + 2
    ElseIf Mid(k, i, 1) = "$" And WorksheetFunction.IsText(Mid(k, i + 1, 1)) And IsNumeric(Mid(k, i + 3, 1)) Then     '$A$1
        Temp = Temp & Mid(k, i, 4) & " "
        i = i + 3
    End If
    End If
Next
MsgBox Replace(WorksheetFunction.Trim(Temp), " ", ",")
Loi:
Exit Sub
End Sub
Thân.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
hihihi! Cuối cùng cũng ra lò 1 code cùi bắp.
Mã:
Sub chay()
On Error GoTo Loi
Dim k  As String, cel As Range
Set cel = Application.InputBox("Chon cells chua cong thuc:", Type:=8)
k = cel.Formula
k = Replace(k, "=", " ")
k = Replace(k, "^", " ")
k = Replace(k, "*", " ")
k = Replace(k, "/", " ")
k = Replace(k, "+", " ")
k = Replace(k, "-", " ")
k = Replace(k, ">", " ")
k = Replace(k, "<", " ")
For i = 1 To Len(k)
    If Mid(k, i, 1) <> " " And Mid(k, i, 1) <> "," Then
    If WorksheetFunction.IsText(Mid(k, i, 1)) And IsNumeric(Mid(k, i + 1, 1)) Then            'A1
        Temp = Temp & Mid(k, i, 2) & " "
        i = i + 1
    ElseIf Mid(k, i, 1) = "$" And WorksheetFunction.IsText(Mid(k, i + 1, 1)) And IsNumeric(Mid(k, i + 2, 1)) Then    '$A1
        Temp = Temp & Mid(k, i, 3) & " "
        i = i + 2
    ElseIf WorksheetFunction.IsText(Mid(k, i, 1)) And Mid(k, i + 1, 1) = "$" And IsNumeric(Mid(k, i + 2, 1)) Then     'A$1
        Temp = Temp & Mid(k, i, 3) & " "
        i = i + 2
    ElseIf Mid(k, i, 1) = "$" And WorksheetFunction.IsText(Mid(k, i + 1, 1)) And IsNumeric(Mid(k, i + 3, 1)) Then     '$A$1
        Temp = Temp & Mid(k, i, 4) & " "
        i = i + 3
    End If
    End If
Next
MsgBox Replace(WorksheetFunction.Trim(Temp), " ", ",")
Loi:
Exit Sub
End Sub
Thân.
File đính kèm của bạn, cell D11 chứa công thức
PHP:
=IF(D7=5,SUM(D2:D5)*9+B8-8,IF(C4>5,1,0))
Giở tôi sửa lại:
PHP:
=IF(Sheet2!D7=5,SUM(D2:D5)*9+B8-8,IF(C4>5,1,0))
thì thế nào?
Khác sheet mới khó chứ cùng sheet thì tôi chỉ cần:
- Chọn cell
- Bấm tổ hợp phím Ctrl + [ là ra
 
Upvote 0
Lệnh DirectPrecedents này dùng không chuẩn lắm bác ơi!
[G5]=D5+E5*(E8/E6-E7)
Thì DirectPrecedents = $D$5,$E$5:$E$8.
Nó tự gộp các vùng lại với nhau luôn.
Thân.
 
Upvote 0
Code thấy ớn đây!
Mã:
Sub chay()
'On Error GoTo Loi
Dim k  As String, cel As Range, shstr As String, Sh As Worksheets
Set cel = Application.InputBox("Chon cells chua cong thuc:", Type:=8)
k = cel.Formula
k = Replace(k, "=", " ")
k = Replace(k, "^", " ")
k = Replace(k, "*", " ")
k = Replace(k, "/", " ")
k = Replace(k, "+", " ")
k = Replace(k, "-", " ")
k = Replace(k, ">", " ")
k = Replace(k, "<", " ")
temp = xdsheet(k)
k = xdsheet(k, True)
For i = 1 To Len(k)
    If Mid(k, i, 1) <> " " And Mid(k, i, 1) <> "," Then
    If WorksheetFunction.IsText(Mid(k, i, 1)) And IsNumeric(Mid(k, i + 1, 1)) Then           'A1
        temp = temp & Mid(k, i, 2) & " "
        i = i + 1
    ElseIf Mid(k, i, 1) = "$" And WorksheetFunction.IsText(Mid(k, i + 1, 1)) And IsNumeric(Mid(k, i + 2, 1)) Then    '$A1
        temp = temp & Mid(k, i, 3) & " "
        i = i + 2
    ElseIf WorksheetFunction.IsText(Mid(k, i, 1)) And Mid(k, i + 1, 1) = "$" And IsNumeric(Mid(k, i + 2, 1)) Then     'A$1
        temp = temp & Mid(k, i, 3) & " "
        i = i + 2
    ElseIf Mid(k, i, 1) = "$" And WorksheetFunction.IsText(Mid(k, i + 1, 1)) And IsNumeric(Mid(k, i + 3, 1)) Then     '$A$1
        temp = temp & Mid(k, i, 4) & " "
        i = i + 3
    End If
    End If
Next
MsgBox Replace(WorksheetFunction.Trim(temp), " ", ",")
Loi:
Exit Sub
End Sub
 
 
Function xdsheet(k As String, Optional dm As Boolean = False)
For Each Sh In Worksheets
For j = 1 To (Len(k) - Len(Replace(k, Sh.Name, ""))) / Len(Sh.Name)
i = InStr(1, k, Sh.Name)
    If WorksheetFunction.IsText(Mid(k, i + Len(Sh.Name) + 1, 1)) And IsNumeric(Mid(k, i + Len(Sh.Name) + 2, 1)) Then    'A1
        temp = temp & Mid(k, i, Len(Sh.Name) + 3) & " "
        k = Replace(k, Mid(k, i, Len(Sh.Name) + 3), "")
    ElseIf Mid(k, i + Len(Sh.Name) + 1, 1) = "$" And WorksheetFunction.IsText(Mid(k, i + Len(Sh.Name) + 2, 1)) And IsNumeric(Mid(k, i + Len(Sh.Name) + 3, 1)) Then   '$A1
        temp = temp & Mid(k, i, Len(Sh.Name) + 4) & " "
        k = Replace(k, Mid(k, i, Len(Sh.Name) + 4), "")
    ElseIf WorksheetFunction.IsText(Mid(k, i + Len(Sh.Name) + 1, 1)) And Mid(k, i + Len(Sh.Name) + 2, 1) = "$" And IsNumeric(Mid(k, i + Len(Sh.Name) + 3, 1)) Then    'A$1
        temp = temp & Mid(k, i, Len(Sh.Name) + 4) & " "
        k = Replace(k, Mid(k, i, Len(Sh.Name) + 4), "")
    ElseIf Mid(k, i + Len(Sh.Name) + 1, 1) = "$" And WorksheetFunction.IsText(Mid(k, i + Len(Sh.Name) + 2, 1)) And IsNumeric(Mid(k, i + Len(Sh.Name) + 4, 1)) Then    '$A$1
        temp = temp & Mid(k, i, Len(Sh.Name) + 5) & " "
        k = Replace(k, Mid(k, i, Len(Sh.Name) + 5), "")
    End If
Next
Next
If dm Then xdsheet = k Else: xdsheet = temp
End Function
Thân.
 

File đính kèm

Upvote 0
Lệnh DirectPrecedents này dùng không chuẩn lắm bác ơi!
[G5]=D5+E5*(E8/E6-E7)
Thì DirectPrecedents = $D$5,$E$5:$E$8.
Nó tự gộp các vùng lại với nhau luôn.
Thân.
Đâu có sao đâu ---> Như vậy ta biết rằng các cell từ E5 đến E8 đều là tham chiếu
Và nếu bạn muốn tách riêng từng cell thì cũng đâu phải chuyện khó gì
-----------
Code cuối cùng cũng chưa chính xác... Ví dụ cell F14 có công thức:
PHP:
=IF(Sheet1!D7=5,SUM(D2:D5)*9+Sheet2!B8-8,IF(Sheet3!C$4>5,1,0))
Sau khi chạy code, nó ra kết quả:
Sheet1!D7,Sheet2!B8,Sheet3!C$4,D2,D5
Mà lý ra phải
Sheet1!D7,Sheet2!B8,Sheet3!C$4,D2:D5
hoặc
Sheet1!D7,Sheet2!B8,Sheet3!C$4,D2, D3, D4, D5
 
Lần chỉnh sửa cuối:
Upvote 0
rủi địa chỉ có dạng A1:A2,$A1:$A2,$A$1:$A$2,A$1:A$2. còn +,-,x,:, nữa rủi trong ô A3 của em có công thức là 19+20 nói chung nó nhiều trường hợp quá em không nghĩ ra cách gì để lấy được (Ý em là em muốn suy từ công thức đó gồm những địa chỉ của ô nà) Ví dụ tại A1 “=Sum(A2:A3)” lấy ra A2A3 hay A2:A3 cũng được
A1 “= $A$2+$A$3” lấy ra $A$2 và $A$3
Tại tác giả cho rằng được mà!
Còn cái của bạn có 1 vấn đề nhỏ là nếu trong Function mà vùng dữ liệu nằm lồng vào nhau như kiểu hàm DSUM thì DirectPrecedents luôn cho ra vùng tổng? Vậy làm sao đây?
Còn việc thứ tự lọc thì em chưa nghĩ ra được cách ghép chúng lại theo trình tự được? Nó cần hai vòng lặp chạy gộp cùng lúc vào nhau? Em bí rùi, đành phải viết vậy thôi!
Thân.
 
Upvote 0
Code trên của bạn rất hay. Nhưng mình tìm thấy 1 lỗi nữa!
Nếu hàm là vùng dữ liệu của Sheet khác thì nó chỉ lấy giá trị đầu mà không lấy vị trí cuối của vùng dữ liệu.
Ví dụ:
=Sum(Sheet3!D3:D9)
thì nó trả về!
Sheet3!D3,D9
Xin bổ sung thêm!
 
Upvote 0
Tại tác giả cho rằng được mà!
Còn cái của bạn có 1 vấn đề nhỏ là nếu trong Function mà vùng dữ liệu nằm lồng vào nhau như kiểu hàm DSUM thì DirectPrecedents luôn cho ra vùng tổng? Vậy làm sao đây?
Còn việc thứ tự lọc thì em chưa nghĩ ra được cách ghép chúng lại theo trình tự được? Nó cần hai vòng lặp chạy gộp cùng lúc vào nhau? Em bí rùi, đành phải viết vậy thôi!
Thân.
Sao mà được chứ
Với công thức này:
=SUM(C4:C6,E7:E8)
Bạn định lấy C4 và E8 thôi sao?
 
Upvote 0
=SUM(C4:C6,E7:E8)
KQ = C4,C6,E7,E8
Hiện em chỉ làm được vậy thôi!
Thân.
 
Upvote 0
=SUM(C4:C6,E7:E8)
KQ = C4,C6,E7,E8
Hiện em chỉ làm được vậy thôi!
Thân.
Vâng!
Đây là 1 bài toán khó nhai
Lấy ví dụ thế này để thấy rằng code cuối cùng của bạn vẫn còn nhiều cái cần phải cải tiến thêm:
- Tôi tạo 1 name tên là ZZZ1 có Refer to =A1
- Tại cell I17 tôi gõ công thức =ZZZ1
- Dùng code của bạn để tìm tham chiếu trong cell I17, nó cho kết quả là Z1 (mà lý ra phải là A1)
Thà rằng code bị lổi hoặc không ra kết quả gì chứ đừng nên ra kết quả sai!
Vì thế mà tôi nghĩ với các tham chiếu cùng sheet, tạm thời bạn nên dùng DirectPrecedents, vì nó tỏ ra rất chính xác ---> Phần tham chiếu qua sheet khác thì dùng cách nào tùy bạn
 
Upvote 0
Theo em thấy trong Excel nó hiểu rất rõ đâu là Text đâu là địa chỉ ô, thậm chí luôn hiểu địa chỉ thuộc trong Name và ở sheet nào luôn. Còn cái Direct kia chỉ là cách thể hiện ở 1 chừng mực nào đó thôi.
Ví như bác gõ =zzz1 thì ngay lặp tức bác sẽ thấy những vùng màu được khoanh sẳn trên bảng tính ngay. Vậy Excel đã tra cứu vào đâu mà được như vậy?
Nếu hiểu được thuật toán của MSExcel thì viết code sẽ dễ hơn nhiều.
Thân.
 
Upvote 0
Đây rùi, mọi người. Tìm từ sáng đến giờ mới ra!
Nhưng khổ nổi kiến thức VBA của em yếu quá đọc chẳng hiểu cái mô tê gì cả?
Có bác nào giỏi lập trình xin dịch giúp em mấy đoạn code dưới ra được không? (dịch từng dòng càng tốt)
Nguồn: http://www.ozgrid.com/forum/showthread.php?t=17028
PHP:
Sub FindPrecedents()
    ' written by Bill Manville
    ' With edits from PaulS
    ' this procedure  finds the  cells which are the direct precedents of the active cell
    Dim rLast As Range, iLinkNum As Integer, iArrowNum As Integer
    Dim stMsg As String
    Dim bNewArrow As Boolean
    Application.ScreenUpdating = False
    ActiveCell.ShowPrecedents
    Set rLast = ActiveCell
    iArrowNum = 1
    iLinkNum = 1
    bNewArrow = True
    Do
        Do
            Application.Goto rLast
            On Error Resume Next
            ActiveCell.NavigateArrow TowardPrecedent:=True, ArrowNumber:=iArrowNum, LinkNumber:=iLinkNum
            If Err.Number > 0 Then Exit Do
            On Error GoTo 0
            If rLast.Address(external:=True) = ActiveCell.Address(external:=True) Then Exit Do
            bNewArrow = False
            If rLast.Worksheet.Parent.Name = ActiveCell.Worksheet.Parent.Name Then
                If rLast.Worksheet.Name = ActiveCell.Parent.Name Then
                    ' local
                    stMsg = stMsg & vbNewLine & Selection.Address
                Else
                    stMsg = stMsg & vbNewLine & "'" & Selection.Parent.Name & "'!" & Selection.Address
                End If
            Else
                ' external
                stMsg = stMsg & vbNewLine & Selection.Address(external:=True)
            End If
            iLinkNum = iLinkNum + 1  ' try another  link
         Loop
        If bNewArrow Then Exit Do
        iLinkNum = 1
        bNewArrow = True
        iArrowNum = iArrowNum + 1  'try another arrow
    Loop
    rLast.Parent.ClearArrows
    Application.Goto rLast
     MsgBox "Precedents are" & stMsg
    Exit Sub
End Sub
 
Upvote 0
Đây rùi, mọi người. Tìm từ sáng đến giờ mới ra!
Nhưng khổ nổi kiến thức VBA của em yếu quá đọc chẳng hiểu cái mô tê gì cả?
Có bác nào giỏi lập trình xin dịch giúp em mấy đoạn code dưới ra được không? (dịch từng dòng càng tốt)
Nguồn: http://www.ozgrid.com/forum/showthread.php?t=17028
Code này dùng chiêu ShowPrecedents hơi bị lợi hai
Cũng không khó khăn gì lắm
Bạn có thể dùng code này để thí nghiệm
PHP:
Sub Test()
ActiveCell.ShowPrecedents
End Sub
Chọn 1 cell chứa công thức và chạy code, sẽ thấy những mũi tên hiện ra chỉ đến các tham chiếu
Mục đích cuối cùng của code là "chạy theo" các mũi tên này và "thu gôm" địa chỉ
Vậy thôi!
 
Upvote 0
Ở đây có rất nhiều hàm em ko hiều cách dùng. Bác có thể hướng dẫn rõ thêm được không ạ?
Ví dụ: obj.NavigateArrow; obj.Parent
Và nếu viết dưới dạng For.. next thì code này phải chỉnh lại như thế nào?
 
Upvote 0
Ở đây có rất nhiều hàm em ko hiều cách dùng. Bác có thể hướng dẫn rõ thêm được không ạ?
Ví dụ: obj.NavigateArrow; obj.Parent
Và nếu viết dưới dạng For.. next thì code này phải chỉnh lại như thế nào?
Mấy cái có liên quan đến Arrow là ứng dụng trong menu Tools\Formula Auditing ---> Bạn có thể record macro để tìm hiểu
Riêng chữ Parent, dịch sang tiếng Việt là CHA MẸ ---> Range("A1").Parent là CHA MẸ của Range("A1"), cũng tức là ActiveSheet ---> Vậy Range("A1").Parent.Name chính là TÊN SHEET chứa cell A1
Nói thêm: Lệnh nào trong VBA mà bạn chưa hiểu, hãy bôi đen nó và F1 ---> Ra tất
 
Upvote 0
Web KT

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

Back
Top Bottom