Hỏi về vị trí của cell hiện hành (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

feelingyes

Thành viên tiêu biểu
Tham gia
24/9/07
Bài viết
459
Được thích
395
Nghề nghiệp
Economic
Các bác xem file sẽ thấy cột ngày nhập cuối cùng (last update) vi dụ là 01/03/2007 do ta nhập ở cột AG (số lượng)
Sau đó Các cột ngày khi ta không dùng sẽ ẩn nó đi.
Nhưng em đang loay hoay tìm cách sao cho khi unhide cột ngày thì vị trí của ô hiện hành sẽ ở đúng vị trí cột ngày 1/3 =>cột AG
Các anh chị chỉ giáo
 

File đính kèm

Lần chỉnh sửa cuối:
Xác định vị trí cell last update bằng công thức thì tôi biết.. tuy nhiên ra dc số rồi ko biết đưa vào code thế nào.. hic...
Thử test với code
Mã:
Cells(DONG.Value, COT.Value).Select
Nó báo lỗi (DONG là vị trí dòng, COT là vị trí cột)
Chẳng biết thế nào nữa... đúng là code rắc rối... tìm hiểu hoài cũng ko tài nào nhớ dc chứ đừng nói là tùy biến...
 
anhtuan1066 đã viết:
Xác định vị trí cell last update bằng công thức thì tôi biết.. tuy nhiên ra dc số rồi ko biết đưa vào code thế nào.. hic...
Thử test với code
Mã:
Cells(DONG.Value, COT.Value).Select
Nó báo lỗi (DONG là vị trí dòng, COT là vị trí cột)
Chẳng biết thế nào nữa... đúng là code rắc rối... tìm hiểu hoài cũng ko tài nào nhớ dc chứ đừng nói là tùy biến...

Bác có thể nói rõ hơn về vần đề này, em . . chưa hiểu lắm ???
Ẩn cột nào ?? Hàng nào ?? Tại sao ???

Chứ đọc câu hỏi thì thấy vẫn . . chưa hiểu!+-+-+-++-+-+-+

Thân!
 
Có nghĩa là thế này đây (theo tôi hiểu)... Khi bạn ấy gõ xong số 1 vào cell AG34 chẳng hạn, thì đây dc xem là lần cập nhật cuối cùng (từ đó trở đi ko nhập dử liệu nào nữa vào vùng DATE... Vậy thì khi ẩn cột xong, bây giờ unhide ra thì bạn ấy muốn cell hiện hành phải chạy tới đúng ngay AG34, chính là last update ấy... (code Hide và Unhide bạn ấy đã có sẳn trong file rồi)
Tôi dùng công thức đặt name có thể xác định dc vị trí dòng cột của cell này (DONG là vị trí dòng last update, COT là vị trí cột last update).. thế nhưng cho vào code thì ko biết sai chổ nào mà nó ko chạy...
Nếu tôi đặt công thức tại B1 và B2:
B1 = DONG
B2 = COT
Rồi thế vào code:
Mã:
Cells(range("B1").Value, range("B2").Value).Select

Cái này thì OK... chứng tõ thuật toán thì ổn, chỉ sai chổ nào đó về cú pháp... Bắp sửa giùm với!
ANH TUẤN​
 
Bác khai báo lại như sau:

PHP:
Dong = Range("B1")
Cot = Range("B2")
Cells(Dong, Cot).Select

HOẶC:

PHP:
Cells(Cells(2, 1), Cells(2, 2)).Select
 
Cảm ơn Dat2007.. nhưng vấn đề là ở chổ DONG và COT đã có giá trị nào đó rồi... thế tại sao phãi tốn thêm cell B1 và B2?
Có cách nào bõ luôn nó ko?
(Nói rõ hơn 1 chút: DONG và COT là 2 name do tôi tự đặt đễ xác định vị trí dòng cột)
 
anhtuan1066 đã viết:
Cảm ơn Dat2007.. nhưng vấn đề là ở chổ DONG và COT đã có giá trị nào đó rồi... thế tại sao phãi tốn thêm cell B1 và B2?
Có cách nào bõ luôn nó ko?
(Nói rõ hơn 1 chút: DONG và COT là 2 name do tôi tự đặt đễ xác định vị trí dòng cột)
Bác xem nhé :


Nhân đây cũng hỏi các cao thủ là :
Mình định mỗi khi thay đổi Sheet thì sẽ tạo ra 2 Name là LastR và LastC để ghi lại số dòng và cột của ActiveCell (VD :LastR = 3; LastC =5)
Tuy nhiên khi chạy Cells(Range("LastR"), Range("LastC")).Select thì nó lại báo lỗi

Nhưng nếu LastR và LastC nhận giá trị từ 1 ô nào đó thì lại . . OK. Chạy tốt

Vậy làm cách nào để LastR = 3; LastC =5 mà Code trên chạy được nhỉ ???

Thân!
 

File đính kèm

Cách làm của tôi cũng hao hao giống như của Bắp, nhưng tại GA1 và GA2 của tôi là công thức xác định dòng cột luôn.. tiếp theo là đưa GA1 và GA2 vào code, nên ko cần thêm đoạn Private Sub Worksheet_Change
 
Mr Okebab đã viết:
Mình định mỗi khi thay đổi Sheet thì sẽ tạo ra 2 Name là LastR và LastC để ghi lại số dòng và cột của ActiveCell (VD :LastR = 3; LastC =5)
Tuy nhiên khi chạy Cells(Range("LastR"), Range("LastC")).Select thì nó lại báo lỗi

Nhưng nếu LastR và LastC nhận giá trị từ 1 ô nào đó thì lại . . OK. Chạy tốt

Vậy làm cách nào để LastR = 3; LastC =5 mà Code trên chạy được nhỉ ???

Dạo này cuối năm bận việc quá chắc các bác quên mất cú pháp của Cells và Range trong VBA rồi

Cells(RowIndex,ColumnIndex) vậy nếu LastR = 3; LastC =5 => Cells(LastR,LastC).Select là xong <=> Range("C5").Select

Còn nếu dùng Cells(Range("LastR"), Range("LastC")).Select thì báo lỗi là đúng vì Range("C5").Select hoặc Range(3,5).Select thì mới đúng cú pháp
 
Vậy trường hợp của tôi thì thế nào?
Tôi đặt name
Mã:
DONG =MAX((FG!$E$4:$AH$1000<>"")*ROW(FG!$A$4:$A$1000))
và COT =MAX((FG!$E$4:$AH$1000<>"")*COLUMN(FG!$E$1:$AH$1))
Vậy mà đưa nó vào code thì báo lỗi đoạn này:
Mã:
Cells(DONG, COT).Select
Thế nhưng nếu tại C1 gõ công thức =DONG C2 gõ công thức =COT rồi đưa vào code thì ko có vấn đề gì
Mã:
Cells(Range("C1").Value, Range("C2").Value).Select
Mong dc chỉ giáo thêm!
ANH TUẤN
 
dat2007 đã viết:
Dạo này cuối năm bận việc quá chắc các bác quên mất cú pháp của Cells và Range trong VBA rồi

Cells(RowIndex,ColumnIndex) vậy nếu LastR = 3; LastC =5 => Cells(LastR,LastC).Select là xong <=> Range("C5").Select

Còn nếu dùng Cells(Range("LastR"), Range("LastC")).Select thì báo lỗi là đúng vì Range("C5").Select hoặc Range(3,5).Select thì mới đúng cú pháp

Không được bác ạ. Bác hãy sửa trực tiếp vào File VD mà xem

Thân!
 
Bác sử dụng như sau nhé!
Mã:
Cells(Range("LastR").Value, Range("LastC").Value).Select
 
nvson đã viết:
Bác sử dụng như sau nhé!
Mã:
Cells(Range("LastR").Value, Range("LastC").Value).Select

Không được nếu LastR và LastC là hằng số
Nếu LastR và LastC ham chiếu đến 1 ô khác (là số) thì lại OK.

Thế mới lạ chứ.

Cứ thử xem!

Thân!
 
Mã:
Cells(Range("LastR").Value, Range("LastC").Value).Select
Cú pháp của Cells là Cells(dòng, cột) với dòng, cột là số (1<=dòng<=65536) (1<=cột<=256)
Còn Range là Range(địa chỉ)
Cells(Range("LastR").Value, Range("LastC").Value).Select sai vì nếu dùng Range thì LastR phải là địa chỉ.

Mã:
Cells(DONG, COT).Select
Tôi thử lấy giá trị của name dong, cot trực tiếp nhưng không được, nhưng qua trung gian của 1 ô trên sheet thì được.
Cells(1, 1).Formula = "=cot"
Cells(1, 2).Formula = "=dong"
Cells(Cells(1, 2), Cells(1, 1)).Select
 
phamduylong đã viết:
Mã:
[LIST=1]
[*] Cells([COLOR=red]Range("LastR").Value[/COLOR], Range("LastC").Value).Select sai vì nếu dùng Range thì LastR phải là địa chỉ.
[*] Tôi thử lấy giá trị của name dong, cot trực tiếp nhưng không được, nhưng qua trung gian của 1 ô trên sheet thì được.[/LIST]  [/quote]
1 mâu thuẫn với 2 bác ạ

LastR không cần là địa chỉ.

VD : Với [B]Msgbox Range("LastR").Value[/B]

Nếu LastR tham chiếu đến 1 ô thì   . .  OK.
Còn nếu nó là 1 hằng số (1,2,3 . . . ) thì nó sẽ báo lỗi.

Sao vậy nhỉ ??
 
Cells(Range("LastR").Value, Range("LastC").Value).Select sai vì nếu dùng Range thì LastR phải là địa chỉ.
LastR, LastC là các Name, thực chất nó cũng là 1 vùng đấy.
Không tin bác cứ tạo 2 name LastR, LastC và chạy macro sau:
Mã:
Public Sub Thu()
'Cells(Range("LastR").Value, Range("LastC").Value).Select
MsgBox Range("LastR").Address
End Sub
 
nvson đã viết:
LastR, LastC là các Name, thực chất nó cũng là 1 vùng đấy.
Không tin bác cứ tạo 2 name LastR, LastC và chạy macro sau:
Mã:
Public Sub Thu()
'Cells(Range("LastR").Value, Range("LastC").Value).Select
MsgBox Range("LastR").Address
End Sub

Chỉ là vùng khi nó có tham chiếu, còn nếu nó là hằng thì nó lại không là vùng nữa (cũng chẳng biết nó là gì nữa+-+-+-+)

Khi đó thì MsgBox Range("LastR").Address sẽ báo lỗi.

Sao thế nhỉ ??
Làm thế nào lấy giá trị của LastR khi nó là hằng không ??

Thân!
 
Sao đoạn Code này lại chạy ngon nhỉ?

PHP:
Sub FillCells()
Dim lRow As Long, lColumn As Long
For lRow = 1 To 10
  For lColumn = 1 To 5
    Cells(lRow, lColumn).Value = lRow * lColumn
  Next lColumn
Next lRow
End Sub
 
dat2007 đã viết:
Sao đoạn Code này lại chạy ngon nhỉ?

PHP:
Sub FillCells()
Dim lRow As Long, lColumn As Long
For lRow = 1 To 10
  For lColumn = 1 To 5
    Cells(lRow, lColumn).Value = lRow * lColumn
  Next lColumn
Next lRow
End Sub
Vì lRow là 1 số, còn LastR lại không phải (khi tham chiếu đến 1 hằng)
Còn nó là gì thì . . chưa biết!

Sau 1 hồi tìm hiểu, thì ra nó là name (ai mà chả biết !!)
Vì vậy đành làm cách củ chuối sau :
PHP:
Sub Unhide_date()
    Dim LastR As Long, LastC As Long
    Dim NM As Name
    For Each NM In ThisWorkbook.Names
        If NM.Name = "LastR" Then
            LastR = Val(Mid$(NM.Value, 2, 5))
        ElseIf NM.Name = "LastC" Then
            LastC = Val(Mid$(NM.Value, 2, 5))
        End If
    Next
    Columns("E:AH").EntireColumn.Hidden = False
    Cells(LastR, LastC).Select
    Set NM = Nothing
End Sub

Các bác cho ý kiến nhé

Thân!
 

File đính kèm

Nguyên văn bởi Mr Okebap
Option Explicit
Dim LastC As Long
Dim LastR As Long
Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next
Application.EnableEvents = False
Application.ScreenUpdating = False
If Not Intersect(Target, Range("E4:AI30000")) Is Nothing Then
LastC = Target.Column
LastR = Target.Row
End If
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Sub Hide_Date()
Columns("E:AH").Select
Selection.EntireColumn.Hidden = True
End Sub
Sub Unhide_date()
Columns("E:AH").EntireColumn.Hidden = False
Cells(LastR, LastC).Select
End Sub
Cho mình hỏi:
-Vì sao phải đặt thêm name LastR, LastC?
-Đoạn code trên gây lỗi chỗ nào?
 
voda đã viết:
Cho mình hỏi:
-Vì sao phải đặt thêm name LastR, LastC?
-Đoạn code trên gây lỗi chỗ nào?

  1. Vì đề bài là lưu lại vị trí của ActiveCell khi ta sửa đổi dữ liệu trong vùng Data. Việc lưu này có thể có nhiều cách, tuy nhiên lại không muốn lưu vị trí đó ra 2 Cell nên em nghĩ rằng đưa vào Name là hợp lý. Vì vậy mới có 2 Name trên
  2. Bác hãy theo dõi các bài ở trên.
Thân!
 
feelingyes đã viết:
Không ngờ một câu hỏi tưởng chừng như "bình thường" của em lại làm các anh đau đầu như vậy!
Hic! lấy gì tạ ơn đây!
Bạn chú ý rằng về nguyên tắc thì yêu cầu của bạn hoàn toàn có thể làm dc... Tuy nhiên ở đây mọi người đang vướng ở chổ là khi xác định dc ví trí cell rồi, nếu đặt nó thành 1 name thì lại ko đưa dc vào code... Nếu cứ lấy đại kết quả tại 2 cell thì... xem như bài toán đã giãi quyết xong...
Ở đây đang bàn về tối ưu và thẫm mỹ trong giãi thuật... Rõ ràng bỏ dc 2 cell phụ này sẽ có cảm giác bài toán hay hơn, và giãi thuật có vẽ thẩm mỹ hơn... Đó mới chính là vấn đề!
ANH TUẤN
 
Các anh ơi, bây giờ yêu cầu bài của em là Column hiện hành cũng được, ví dụ lần cuối cùng em xuât là 1/3/2007
Sau đó hide và unhide thì vị trí sẽ nhẩy về cột ngày xuất gần nhất
Các anh giúp em code với
 
nvson đã viết:
LastR, LastC là các Name, thực chất nó cũng là 1 vùng đấy.
Trước đây tôi cũng nghĩ name là một vùng. LastR, LastC đúng là vùng. Nhưng dong, cot cũng là name nhưng lại cho ra giá trị. Công thức =dong. =cot lại cho ra kết quả là số như là một function.

2 lệnh MsgBox Range("LastR").Address Range("LastR").Select đúng vì LastR là vùng
Nhưng MsgBox Range("dong").AddressRange("dong").Select báo lỗi !
Như vậy name dong, cot bản chất nó không phải là vùng Range như LastR, LastC như chúng ta vẫn nghĩ.
Còn nhiều điều về name mà chúng ta chưa biết đến!
 
feelingyes đã viết:
Các anh ơi, bây giờ yêu cầu bài của em là Column hiện hành cũng được, ví dụ lần cuối cùng em xuât là 1/3/2007
Sau đó hide và unhide thì vị trí sẽ nhẩy về cột ngày xuất gần nhất
Các anh giúp em code với
Được sự chỉ dẫn của NVSON nên đã sửa lại mấy dòng Code "chuối" trện

Các bác theo dõi nhé :

PHP:
Sub Unhide_date()
    Dim LastR As Long, LastC As Long
    LastR = Evaluate(Names("LastR").RefersTo)
    LastC = Evaluate(Names("LastC").RefersTo)
    Columns("E:AH").EntireColumn.Hidden = False
    Cells(LastR, LastC).Select
End Sub

Quả là tiện thât.

Cảm ơn NVSON nhiều!! Chưa vợ có khác, còn minh mẫn lắm

Thân!
 

File đính kèm

Mình xin cải tiến thêm 1 chút nữa:
Private Sub Worksheet_Change(ByVal Target As Range)
..........
ActiveWorkbook.Names.Add Name:="LastCR", RefersToR1C1:=Target
...........
End Sub
Sub Unhide_date()
Dim LastAd As String, LastRa As String
.... LastAd = ActiveWorkbook.Names("LastCR").RefersTo
.... LastRa = Mid$(LastAd, 5, 10)
.... Columns("E:AH").EntireColumn.Hidden = False
.... Range(LastRa).Select
End Sub
Để học tập thôi. Các bạn cho ý kiến nhé.
 
feelingyes đã viết:
Các bác xem file sẽ thấy cột ngày nhập cuối cùng (last update) vi dụ là 01/03/2007 do ta nhập ở cột AG (số lượng)
Sau đó Các cột ngày khi ta không dùng sẽ ẩn nó đi.
Nhưng em đang loay hoay tìm cách sao cho khi unhide cột ngày thì vị trí của ô hiện hành sẽ ở đúng vị trí cột ngày 1/3 =>cột AG
Các anh chị chỉ giáo
Cach làm này khác feelingyes 2 điểm:
1. Không dùng name LastR và LastC, nếu ô nhập trong vùng E4:AI30000 thì ghi số dòng vào GA1 và cột vào GA2.
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
r = Target.Row
c = Target.Column
If (r >= 4 And r <= 30000) And (c >= 5 And c <= 35) Then
  Cells(1, 183) = Target.Row
  Cells(2, 183) = Target.Column
End If
End Sub

2. Hai Sub UnHide_Date và Hide_Date không tạo trong sheet "FG" mà tạo trong Module để có thể gán phím tắt. Thao tác ẩn, hiện cột nhanh hơn. Do Sub ở trong Module, nên nó phải kiểm tra sheet active có phải là "FG" không, nếu đúng mới thi hành.

Mã:
Sub UnHide_Date()
'
' UnHide_Date Macro
' Macro recorded 28/11/2007 by LAIVUNG
'
' Keyboard Shortcut: Ctrl+Shift+U
'
If ActiveWorkbook.Name = ThisWorkbook.Name And ActiveSheet.Name = "FG" Then
  Columns("E:AH").EntireColumn.Hidden = False
  Cells(Cells(1, 183), Cells(2, 183)).Select
End If
End Sub

Mã:
Sub Hide_Date()
'
' Hide_Date Macro
' Macro recorded 28/11/2007 by LAIVUNG
'
' Keyboard Shortcut: Ctrl+Shift+H
'
If ActiveWorkbook.Name = ThisWorkbook.Name And ActiveSheet.Name = "FG" Then
  Columns("E:AH").EntireColumn.Hidden = True
  Cells(4, 1).Select
End If
End Sub

Gởi kèm SoMax.zip cho thấy sự khác nhau giữa name vùng và name công thức cho nvson
 

File đính kèm

Lần chỉnh sửa cuối:
anhtuan1066 đã viết:
Oh... rắc rối thế nhỉ? Nhưng rõ ràng thầy đã cho biến đó là rc rồi mà... thế ko cho thẳng rc vào code dc sao?
Dùng biến r và c viết If - End If gọn hơn. Không dùng r, c cũng được nhưng viết dài hơn và nhất là dễ sai.
Dùng biến r, c:
Mã:
r = Target.Row
c = Target.Column
If (r >= 4 And r <= 30000) And (c >= 5 And c <= 35) Then
Cells(1, 183) = r 
Cells(2, 183) = c
End If

Không dùng biến r,c:
Mã:
If (Target.Row >= 4 And Target.Row <= 30000) And (Target.Column >= 5 And Target.Column <= 35) Then
Cells(1, 183) = Target.Row
Cells(2, 183) = Target.Column
End If
 

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

Back
Top Bottom