Đố vui về VBA! (1 người xem)

Liên hệ QC

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

anhtuan1066

Thành viên gạo cội
Tham gia
10/3/07
Bài viết
5,802
Được thích
6,912
Nhằm cũng cố kiến thức về VBA cho các bạn mới bắt đầu và cả những bạn đang ứng dụng mà chưa hiểu nhiều về nó, tôi mở topic này với mong mõi qua những câu hỏi vui, các bạn sẽ nhận định lại sự hiểu biết cũa mình... (Kễ cã chính tôi cũng đang tập tành nên có rất nhiều cái chưa biết)
Mong rằng topic sẽ mang đến cho các bạn những khám phá thú vị với những cái tưỡng chừng như đã biết
Mong nhận dc bài viết về câu đố cũa các cao thủ! Còn các bạn mới thì đừng ngại khi đưa ra ý kiến cũa mình.. Có sai có sữa sẽ hoàn thiện!
Tôi xin mỡ màn trước bằng 1 câu hỏi đơn giãn
ANH TUẤN

CÂU HỎI 1: Tại sao biến K ko hoạt động?
Tôi muốn khi nhấn vào 1 button thì cell A1 sẽ tăng lên 1 đơn vị... Tôi đã làm như sau:
-Tạo 1 Command Button (nút nhấn thuộc thanh Control Toolbox), click phải chuột lên nút nhấn, chọn View code, rồi gõ vào đoạn code sau:
PHP:
Private Sub CommandButton1_Click()
   K = K + 1
   Range("A1").Value = K
End Sub
Ban đầu K chưa có gì, xem như =0, nhấn nút lần thứ nhất thì K dc tăng thêm 1, vậy K hiện tại sẽ bằng 1, và gán K vào cell A1 thì đương nhiên A1 sẽ =1... Nhấn nút lần 2, K lại dc tăng thêm 1 nên hiện tại K sẽ =2 và cell A1 cũng sẽ =2... vân vân.. từ đó diễn tiến tiếp...
Hi.. hi.. Điều này nghe qua có vẽ rất hợp lý, ấy thế mà khi nhấn nút nó chỉ hoạt động dc duy nhất 1 lần (A1 = 1) rồi thôi ko nhút nhít nữa...
Các bạn có thể giãi thích tại sao lại như thế ko? Tại sao những lần nhấn nút sau đó K lại ko tăng thêm tí nào (vì thực tế A1 vẫn cứ = 1 hoài) ?
ANH TUẤN
 
Dịch chuyển mũi tên xổ xuống của Validation

Ngồi buồn "vọc" thằng Validation, thấy có trò này cũng hơi buồn cười, post lên cho bà con xem

[video=youtube;A6V_xDD38vA]http://www.youtube.com/watch?v=A6V_xDD38vA[/video]


Có ai làm được giống vậy không ta?
Ẹc... Ẹc...
 
Upvote 0
Đại khái chắc như hình "Vali đi lạc" sau:

vali-di lac.jpg

Vụ này chắc ndu và lão chết tiệt cùng tình cờ phát hiện khi xử 1 file trong topic xoá object rác.
 
Lần chỉnh sửa cuối:
Upvote 0
Hôm nay mạo muội vào đây hỏi một câu, múa rìu qua mắt thợ, hoặc gọi là đố cũng được - đố cho người chưa biết hà hà ...
Trả lời nhanh: Đoạn code này trả về True hay False? không được chạy thử nha
Sub Thu1()
[A1] = "GPE1"
[A2] = "GPA"
Set Tim = Columns("A").Find("GPE")
MsgBox (Not Tim Is Nothing)
End Sub
 
Upvote 0
Nói trật là trật mà, xin mời các Bạn khác.
 
Upvote 0
Nếu mình set Tim như vậy là chắc chắn True rồi cài này nó tìm thấy mà Phủ định của True, False cuối cùng Msgbox là False mà bạn Learning-Excel trả lời không phải True là False rồi
 
Upvote 0
Cả hai Bạn đều sai, kinh nghiệm "xương máu" đó, cảm ơn đi mình giải cho
 
Lần chỉnh sửa cuối:
Upvote 0
Hôm nay mạo muội vào đây hỏi một câu, múa rìu qua mắt thợ, hoặc gọi là đố cũng được - đố cho người chưa biết hà hà ...
Trả lời nhanh: Đoạn code này trả về True hay False? không được chạy thử nha
TRUE cũng trật mà FALSE cũng trật lất luôn
Do Find method anh thanhlanh viết thiếu
Nếu vầy thì ra kết quả = TRUE
Mã:
Sub Thu1()
  Dim Tim As Range
  [A1] = "GPE1"
  [A2] = "GPA"
  Set Tim = Columns("A").Find("GPE", , , [COLOR=red][B]xlPart[/B][/COLOR])
  MsgBox (Not Tim Is Nothing)
End Sub
Còn vầy thì FALSE
Mã:
Sub Thu1()
  Dim Tim As Range
  [A1] = "GPE1"
  [A2] = "GPA"
  Set Tim = Columns("A").Find("GPE", , , [COLOR=red][B]xlWhole[/B][/COLOR])
  MsgBox (Not Tim Is Nothing)
End Sub
Còn nếu ta cố tình bỏ qua cái màu đỏ ở trên thì nó sẽ theo cái sự tìm kiếm của lần trước ---> Lần trước mình tìm chính xác thì giờ chạy code nó sẽ tìm chính xác... Còn lần trước mình tìm gần đúng thì lần này nó cũng sẽ tìm gần đúng
---------------
Kết luận cuối cùng: Có dùng Find Method thì cố mà ghi cho đầy đủ, thiếu 1 tham số có thể gây hậu quả nghiêm trọng
 
Lần chỉnh sửa cuối:
Upvote 0
Đúng là như Anh NDU nói, nhưng do tác giả hỏi trả về TRUE hay FALSE và vì viết thiếu (hoặc sai cấu trúc) của hàm Find thì đã cho kết quả FALSE rồi, và khi Msgbox phủ định của FALSE chỉ có trả vềTRUE thôi. Thực tế chạy code như vậy. Chạy nhiều lần vẫn vậy.
 
Lần chỉnh sửa cuối:
Upvote 0
TRUE cũng trật mà FALSE cũng trật lất luôn
Do Find method anh thanhlanh viết thiếu
Nếu viết đủ thì còn đố gì được nữa, vậy nên mới có mẹo là không được thử chứ nếu được thử chưa chắc trả lời được, Hà hà ...
Vậy nếu viết thiếu mà chạy lần đầu thì sao?
 
Lần chỉnh sửa cuối:
Upvote 0
Nếu viết đủ thì còn đố gì được nữa, Hà hà ...
Vậy nếu viết thiếu mà chạy lần đầu thì sao?
Không chắc! Như em đã nói ở trên:
Còn nếu ta cố tình bỏ qua cái màu đỏ ở trên thì nó sẽ theo cái sự tìm kiếm của lần trước ---> Lần trước mình tìm chính xác thì giờ chạy code nó sẽ tìm chính xác... Còn lần trước mình tìm gần đúng thì lần này nó cũng sẽ tìm gần đúng
 
Upvote 0
Đúng là như Anh NDU nói, nhưng do tác giả hỏi trả về TRUE hay FALSE và vì viết thiếu (hoặc sai cấu trúc) của hàm Find thì đã cho kết quả FALSE rồi, và khi Msgbox phủ định của FALSE chỉ có trả vềTRUE thôi. Thực tế chạy code như vậy. Chạy nhiều lần vẫn vậy.
Cái này cũng sai nha!
 
Upvote 0
Không chắc! Như em đã nói ở trên:

Không ndu à, nếu bỏ qua tham số thì nếu chạy lần đầu nó còn phụ thuột tùy chon Find trên Excel (giả sử như mình tìm gì đó trên Excel trước khi chạy code),hình như mặc định là tìm gần đúng
 
Lần chỉnh sửa cuối:
Upvote 0

Nếu như viết hàm FIND("GPE") như vậy thì mặc định của nó được tính như LookAt:=xlPart, trong trường hợp này thì giá trị trả về GPE1, nhưng nếu Find("GP") thì trả về giá trị GPA. Thêm cái msgbox đó lại trả về TRUE là đúng rồi còn gì?
 
Upvote 0
Nếu như viết hàm FIND("GPE") như vậy thì mặc định của nó được tính như LookAt:=xlPart, trong trường hợp này thì giá trị trả về GPE1, nhưng nếu Find("GP") thì trả về giá trị GPA. Thêm cái msgbox đó lại trả về TRUE là đúng rồi còn gì?

Câu này : MsgBox (Not Tim Is Nothing) = nếu tìm thấy thì trả về là true chớ bạn?
 
Upvote 0
Đúng là như Anh NDU nói, nhưng do tác giả hỏi trả về TRUE hay FALSE và vì viết thiếu (hoặc sai cấu trúc) của hàm Find thì đã cho kết quả FALSE rồi, và khi Msgbox phủ định của FALSE chỉ có trả vềTRUE thôi. Thực tế chạy code như vậy. Chạy nhiều lần vẫn vậy.

Nếu 1 người khác nói rằng False, thực tế chạy ra False, chạy nhiều lần vẫn False thì sao?

Thực tế có xảy ra đấy. Cho nên câu nói của ndu phải hiểu rõ ràng, chứ không thể hiểu sơ sài rồi tuyên bố mạnh miệng.
ndu đã viết:
Còn nếu ta cố tình bỏ qua cái màu đỏ ở trên thì nó sẽ theo cái sự tìm kiếm của lần trước
lần trước phải hiểu là lần sử dụng công cụ find trước khi chạy code của thanhlanh lần đầu tiên. Có thể bằng code, bằng Ctrl F, Ctrl H, bằng menu, ... Có thể là hồi sáng, hôm qua, và có thể là năm ngoái.

Muốn test thì phải test đầy đủ như sau:
PHP:
Sub Thu1()
[A1] = "GPE1"
[A2] = "GPA"
Set Timkiem = Columns("A").Find("LCT", , , xlPart)
Set Tim = Columns("A").Find("GPE")
MsgBox (Not Tim Is Nothing)
End Sub
PHP:
Sub Thu2()
[A1] = "GPE1"
[A2] = "GPA"
Set Timkiem = Columns("A").Find("LCT", , , xlWhole)
Set Tim = Columns("A").Find("GPE")
MsgBox (Not Tim Is Nothing)
End Sub
Thu1 luôn luôn True

Thu2 luôn luôn False
 
Lần chỉnh sửa cuối:
Upvote 0
Vậy rốt cục nó như thế nào Anh nói ra luôn đi nhé!

Ở trên mấy anh đã giải thích hết rồi: Phụ thuộc vào cách tìm trước đó (nhưng chưa tắt Excel), trước đó nếu tìm bằng code, bằng Ctrl + H, hoặc bằng Ctrl + F .... ta tùy chọn kiểu gì thì lần sau nó tìm kiểu đó, còn khi mới khởi động Excel thì nó mặc định là tìm gần đúng: Trong chuỗi "GPE1" có chứa chuỗi "GPE" --> kết quả của tìm gần đúng là: Có tìm thấy.
Còn nếu tìm chính xác thì Cell cần tìm phải chứa chuỗi giống hệt chuỗi cần tìm, không thêm, không bớt kể cả ký tự trắng.
 
Lần chỉnh sửa cuối:
Upvote 0
Không ndu à, nếu bỏ qua tham số thì nếu chạy lần đầu nó còn phụ thuột tùy chon Find trên Excel (giả sử như mình tìm gì đó trên Excel trước khi chạy code),hình như mặc định là tìm gần đúng
Thì em đã nói trước đó rồi còn gì... rất rõ nữa là đàng khác
Còn nếu ta cố tình bỏ qua cái màu đỏ ở trên thì nó sẽ theo cái sự tìm kiếm của lần trước ---> Lần trước mình tìm chính xác thì giờ chạy code nó sẽ tìm chính xác... Còn lần trước mình tìm gần đúng thì lần này nó cũng sẽ tìm gần đúng
chỉ có sư phụ Mỹ là hiểu rất rõ em muốn nói về cái gì
hình như mặc định là tìm gần đúng
Không có tài liệu nào nói cái MẶC ĐỊNH của Excel là như thế nào đâu nha
Vậy rốt cục nó như thế nào Anh nói ra luôn đi nhé!
TRUE hay FALSE là tùy theo từng máy tính, không thể nói chính xác được đâu
------------------------
Nói thêm 1 chút về cái vụ LẦN TRƯỚC: Nó không chỉ có xlPart, xlWhole không thôi mà còn nhiều tham số khác phải quan tâm, như: xlValues hay xlFormulas, MatchCase = True hay False nữa ---> Nhắm mắt nhắm mũi viết đại có khi trên máy mình chạy được còn sang máy khác lại... toi
Ẹc... Ẹc...
 
Upvote 0
Không có tài liệu nào nói cái MẶC ĐỊNH của Excel là như thế nào đâu nha

Mình chưa thấy máy nào mới khởi động Excel mà mục Match entire cell contents trong tùy chọn của công cụ Find được check cả. Đánh dấu check vào, tắt Excel, mở lên lại mất dấu --> mình cho là mặc định nó vậy.
--------------
Khi dùng Find trong VBA với các tham số xlPart hoặc xlWhole cũng làm thay đổi được tùy chọn Match entire cell contents nhưng cũng chỉ có tác dụng trong phiên làm việc đó thôi.
 
Lần chỉnh sửa cuối:
Upvote 0
Mình chưa thấy máy nào mới khởi động Excel mà mục Match entire cell contents trong tùy chọn của công cụ Find được check cả. Đánh dấu check vào, tắt Excel, mở lên lại mất dấu --> mình cho là mặc định nó vậy.
--------------
Khi dùng Find trong VBA với các tham số xlPart hoặc xlWhole cũng làm thay đổi được tùy chọn Match entire cell contents nhưng cũng chỉ có tác dụng trong phiên làm việc đó thôi.
Em không nghĩ thế! Có thể với 1 vài tinh chỉnh nhỏ trong Registry có thể làm cho Match entire cell contents luôn luôn được check cũng không chừng
Anh và mọi người cứ nghiên cứu xem!
Nói tóm lại: Do ta không biết được cái gì là MẶC ĐỊNH nên khi dùng Find Method thôi thì cứ viết cho thật rõ ràng
 
Upvote 0
Bình thường khi nhấn AutoFilter 10 cột dữ liệu ta sẽ được như hình:

Filter1.jpg

Nhưng tôi muốn Filter kiểu khác, mỗi cột filter bắt đầu từ 1 dòng khác nhau:

Filter di lac.jpg

Câu đố là: Làm thế nào để được như vậy?

Câu này ndu biết, trong bài đố vali đi lạc bên trên.

Ghi chú:
Làm xong hông xài như ý mình muốn, nó chạy hông giống ai hết.
 
Upvote 0
Các bạn có thể thêm nút lệnh vào menu của VBE được không?, như hình sau nè:
 

File đính kèm

  • untitled.JPG
    untitled.JPG
    53.6 KB · Đọc: 66
Lần chỉnh sửa cuối:
Upvote 0
Các bạn có thể thêm nút lệnh vào menu của VBE được không?, như hình sau nè:
Chỉ cần thí nghiệm bằng code này:
PHP:
Sub Test()
  Dim Item As CommandBarControl
  For Each Item In Application.VBE.CommandBars("Menu Bar").Controls
    MsgBox Item.Caption
  Next
End Sub
Hoặc:
PHP:
Sub Test()
  Dim Item As CommandBarControl
  For Each Item In Application.VBE.CommandBars("Menu Bar").Controls("Tools").Controls
    MsgBox Item.Caption
  Next
End Sub
là có thể làm gì đó thoải mái ---> Giống như Menu của Workbook
Ẹc... Ẹc...
 
Lần chỉnh sửa cuối:
Upvote 0
Chỉ cần thí nghiệm bằng code này:
PHP:
Sub Test()
  Dim Item As CommandBarControl
  For Each Item In Application.VBE.CommandBars("Menu Bar").Controls
    MsgBox Item.Caption
  Next
End Sub
Hoặc:
PHP:
Sub Test()
  Dim Item As CommandBarControl
  For Each Item In Application.VBE.CommandBars("Menu Bar").Controls("Tools").Controls
    MsgBox Item.Caption
  Next
End Sub
là có thể làm gì đó thoải mái ---> Giống như Menu của Workbook
Ẹc... Ẹc...

Sư phụ thử chạy coi, ví dụ:
PHP:
Sub Test()
    Dim CmdBarItem As CommandBarControl
    With Application.VBE.CommandBars("Menu Bar").Controls("Tools")
        Set CmdBarItem = .Controls.Add
    End With
    With CmdBarItem
        .Caption = "First Item"
        .BeginGroup = True
        .OnAction = "DienDanExcel"
    End With
End Sub
Sub DienDanExcel()
    Sheets(1).Select
    [A1] = "GPE"
End Sub
Sub DeleteMenuItems()
    Application.VBE.CommandBars("Menu Bar").Controls("Tools").Reset
End Sub
Sub Auto_Close()
    DeleteMenuItems
End Sub
 
Upvote 0
Mình chưa thấy máy nào mới khởi động Excel mà mục Match entire cell contents trong tùy chọn của công cụ Find được check cả. Đánh dấu check vào, tắt Excel, mở lên lại mất dấu --> mình cho là mặc định nó vậy.
--------------
Khi dùng Find trong VBA với các tham số xlPart hoặc xlWhole cũng làm thay đổi được tùy chọn Match entire cell contents nhưng cũng chỉ có tác dụng trong phiên làm việc đó thôi.
Cũng cái Find này, khi làm bằng tay thì nó cho mình chọn tùy chọn Within (Workbook hay là Sheet). Nhưng sao khi dùng VBA thì nó không có tùy chọn này cho mình nhỉ. Và nó cũng lấy theo lần tìm kiếm trước đó. Xin hỏi có ai biết cách khắc phục cái này không?
 
Upvote 0
Sư phụ thử chạy coi, ví dụ:
PHP:
Sub Test()
    Dim CmdBarItem As CommandBarControl
    With Application.VBE.CommandBars("Menu Bar").Controls("Tools")
        Set CmdBarItem = .Controls.Add
    End With
    With CmdBarItem
        .Caption = "First Item"
        .BeginGroup = True
        .OnAction = "DienDanExcel"
    End With
End Sub
Sub DienDanExcel()
    Sheets(1).Select
    [A1] = "GPE"
End Sub
Sub DeleteMenuItems()
    Application.VBE.CommandBars("Menu Bar").Controls("Tools").Reset
End Sub
Sub Auto_Close()
    DeleteMenuItems
End Sub
Ý anh muốn nói gì đây? Action nó không được chăng? Muốn làm được điều này phải dùng ClassModule anh ơi
Xem cái này:
http://www.cpearson.com/excel/VbeMenus.aspx
 
Upvote 0
Cũng cái Find này, khi làm bằng tay thì nó cho mình chọn tùy chọn Within (Workbook hay là Sheet). Nhưng sao khi dùng VBA thì nó không có tùy chọn này cho mình nhỉ. Và nó cũng lấy theo lần tìm kiếm trước đó. Xin hỏi có ai biết cách khắc phục cái này không?

Mình nghĩ là cái này nó khác với tìm trong Excel:
- Khi tìm bằng Code mình đã chỉ định một Range (hoặc Name) rồi nên không thể nào là Workbook được.
- Còn trong Excel mình có thể không chọn vùng nào, cứ thế tìm tới, theo hàng hoặc theo cột (tùy chọn) vì vậy nó phải có cái tùy chọn là Wb hay Ws để gi[í hạn.
Theo Help:
expression.Find(What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat)
expression Required. An expression that returns a Range object.

To ndu: Đúng là không có gì Bạn không biết (by Excel).
 
Lần chỉnh sửa cuối:
Upvote 0
Cũng cái Find này, khi làm bằng tay thì nó cho mình chọn tùy chọn Within (Workbook hay là Sheet). Nhưng sao khi dùng VBA thì nó không có tùy chọn này cho mình nhỉ. Và nó cũng lấy theo lần tìm kiếm trước đó. Xin hỏi có ai biết cách khắc phục cái này không?
Có nhiều món bác Bill cho làm bằng tay nhưng lại không cho code để viết, chẳng hạn ta có thể "nén" toàn bộ Pictures trong bảng tính chỉ bằng 1 thao tác, vậy mà lại không thể viết ra thành code
Find Method cũng thuộc dạng này. Search google sẽ thấy rất nhiều người hỏi mà không có giải pháp nào nếu không dùng vòng lập
 
Upvote 0
Mình nghĩ là cái này nó khác với tìm trong Excel:
- Khi tìm bằng Code mình đã chỉ định một Range (hoặc Name) rồi nên không thể nào là Workbook được.
- Còn trong Excel mình có thể không chọn vùng nào, cứ thế tìm tới, theo hàng hoặc theo cột (tùy chọn) vì vậy nó phải có cái tùy chọn là Wb hay Ws để gi[í hạn.
Theo Help:

To ndu: Đúng là không có gì Bạn không biết (by Excel).
Đâu có phải như vậy. Bạn thử dùng Find bằng tay với phạm vi toàn Workbook. Sau đó dùng Find bằng Macro. Macro cũng sẽ tìm trên phạm vi toàn Workbook luôn.
 
Upvote 0
Đâu có phải như vậy. Bạn thử dùng Find bằng tay với phạm vi toàn Workbook. Sau đó dùng Find bằng Macro. Macro cũng sẽ tìm trên phạm vi toàn Workbook luôn.
Dù là vậy cũng chẳng xài được vào việc gì, thậm chí còn gây nhầm lẫn đáng tiếc nếu mang code sang máy khác nữa.
Nói chung vụ này tôi đã tìm khắp google rồi mà vẫn KHÔNG CÓ CÁCH
 
Upvote 0
Dù là vậy cũng chẳng xài được vào việc gì, thậm chí còn gây nhầm lẫn đáng tiếc nếu mang code sang máy khác nữa.
Nói chung vụ này tôi đã tìm khắp google rồi mà vẫn KHÔNG CÓ CÁCH
Vì tôi có viết một đoạn code, trong code dùng phương thức Replace cho một Sheet cố định. Nhưng nếu người dùng dùng Find trên phạm vi toàn Workbook thì sau đó code sẽ chạy sai.

Anh Bill không cho thì đành bó tay vậy //////
 
Upvote 0
Vì tôi có viết một đoạn code, trong code dùng phương thức Replace cho một Sheet cố định. Nhưng nếu người dùng dùng Find trên phạm vi toàn Workbook thì sau đó code sẽ chạy sai.

Anh Bill không cho thì đành bó tay vậy //////

Bạn cho mình một ví dụ đi, sao mình cố cho nó xảy ra giống Bạn mà không được. Nó chỉ tìm khi có địa chỉ được chỉ định và chỉ tìm trên sheet hiện hành dù trước đó có tìm bằng tay trên toàn Wb
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn cho mình một ví dụ đi, sao mình cố cho nó xảy ra giống Bạn mà không được. Nó chỉ tìm khi có địa chỉ được chỉ định và chỉ tìm trên sheet hiện hành dù trước đó có tìm bằng tay trên toàn Wb
Bạn Find bằng tay trên toàn Workbook rồi sau đó chạy code. Sang Sheet2 kiểm tra lại.
Cũng code đó nhưng trước khi chạy code bạn find trên Worksheet thôi thì kết quả lại khác.
 

File đính kèm

Upvote 0
Bạn Find bằng tay trên toàn Workbook rồi sau đó chạy code. Sang Sheet2 kiểm tra lại.
Cũng code đó nhưng trước khi chạy code bạn find trên Worksheet thôi thì kết quả lại khác.

Bạn thêm một câu lệnh này vào thử
Set Rng = Sheets(1).UsedRange.Find("*", , , xlPart)

PHP:
Sub Test()
    Application.ScreenUpdating = False
    Set Rng = Sheets(1).UsedRange.Find("*", , , xlPart)
        If Sheet1.[A1].HasFormula Then
            Sheet1.UsedRange.Replace What:="=", Replacement:="!@#", LookAt:=xlPart
        Else
            Sheet1.UsedRange.Replace What:="!@#", Replacement:="=", LookAt:=xlPart
        End If
        Application.ScreenUpdating = True
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Một bài toán tách số

Tôi có dữ liệu thế này:
4342gfgdfg
2342sdbdvb
345dvbcvb
54353
gdfgdfg

Các chuổi tuân thủ nguyên tắc:
- Hoặc không chứa bất kỳ số nào
- Hoặc chỉ toàn là số
- Hoặc lẩn lộn vừa số vừa chữ nhưng số luôn nằm cạnh nhau về bên trái còn chữ thì nằm bên phải
Yêu cầu tách lấy số:
4342gfgdfg ---> 4342
2342sdbdvb ----> 2342
345dvbcvb ----> 345
54353 ----> 54353
gdfgdfg ----> 0

Code không dùng vòng lập và nếu code ngắn dưới 3 dòng thì càng tốt...
 
Upvote 0
Nếu như nguyên tắc của Anh Tuan thì code sau có thể

Msgbox Val("1325gfghtv")
 
Upvote 0
Lần chỉnh sửa cuối:
Upvote 0
Upvote 0
Mình nghĩ khai báo biến I As String cũng ổn hay sao á
gán biến I cho vùng kết quả
 
Upvote 0
Theo em thì sửa code của Bác Cò lại một chút.
PHP:
 StrReverse(Val(StrReverse(str))) * 10 ^ (Len(str) - Len(RTrim(Replace(str, 0, " "))))
Tôi nghĩ vầy cũng được chứ nhỉ:
PHP:
MsgBox Int(StrReverse(Val("1" & StrReverse(Text))) / 10)
Với Text là chuổi cho trước
---------------------------------------
Mình nghĩ khai báo biến I As String cũng ổn hay sao á
gán biến I cho vùng kết quả
Hình như không được anh à!
 
Upvote 0
Sao em điền có chuỗi vào thì MsgBox Int(StrReverse(Val("1" & StrReverse("12345dfgd"))) / 10) nó hiện bằng không vậy anh Ndu không biết text trong code là cái gì, cho em công thức Function cái này luôn đi, em không hiểu
 
Upvote 0
Sao em điền có chuỗi vào thì MsgBox Int(StrReverse(Val("1" & StrReverse("12345dfgd"))) / 10) nó hiện bằng không vậy anh Ndu không biết text trong code là cái gì, cho em công thức Function cái này luôn đi, em không hiểu

Với Text là tùy ý, ví dụ Text = "nmhung49" thì chạy code sẽ ra 49

Bạn thử nó với hàm tự tạo:

PHP:
Function NumberSeparate(Text As String) As Double
  NumberSeparate = Int(StrReverse(Val("1" & StrReverse(Text))) / 10)
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
Hihi, nhờ Thầy Sealand mình mới biết cái Val ....val này, đề bài này làm phải có yêu cầu kiểu dữ liệu của kết quả mới làm trúng được, còn nếu không dùng vòng lặp thì "chơi" VbScript.RegExp cho nó "phẻ", khỏi suy tư cho cực
Híc
 
Upvote 0
Sao em điền có chuỗi vào thì MsgBox Int(StrReverse(Val("1" & StrReverse("12345dfgd"))) / 10) nó hiện bằng không vậy anh Ndu không biết text trong code là cái gì, cho em công thức Function cái này luôn đi, em không hiểu
Ở trên nói rồi mà:
- Nếu số nằm trước chữ thì MsgBox Val("12345dfgd") là đủ
- Nếu số nằm sau chữ thì.. dùng cái vừa rồi
 
Upvote 0
Hihi, nhờ Thầy Sealand mình mới biết cái Val ....val này, đề bài này làm phải có yêu cầu kiểu dữ liệu của kết quả mới làm trúng được, còn nếu không dùng vòng lặp thì "chơi" VbScript.RegExp cho nó "phẻ", khỏi suy tư cho cực
Híc
Câu đố này không nhằm mục đích xử lý chuổi hay tách số gì cả! Em chỉ muốn giới thiệu hàm Val thôi anh à! Vì có khi ta đã từng xài nhưng không để ý lắm
Ngoài ra cũng đâu phải bài toán tách số nào cũng dùng VbScript.RegExp được đâu anh
Ví dụ:
Cho chuổi 123abc456
Người ta chỉ muốn lấy số 123 thôi
-------------------------------------
Thử bài toán này để hiểu thêm về Val:
- Gõ ngày tháng vào cell A1 (ngày tháng đúng chuẩn)
- Dùng câu lệnh MsgBox Val(Range("A1").Value) xem kết quả là bao nhiêu?
Từ đó so sánh Val với CDate, CLng, CDbl
Rất thú vị đấy
 
Lần chỉnh sửa cuối:
Upvote 0
Mình lại đang phân vân, nếu mã số cho ra là NGHIA00001 thì nếu dùng Int(StrReverse(Val("1" & StrReverse(Text))) / 10) thì cho ra 1, nhưng lại muốn phải là 00001 thì không giải quyết được. Mặt khác, nếu text chỉ là NGHIA thì dùng dòng lệnh trên cho ra 0 mà thực tế, không có số 0 nào trong text. Cho nên phải thay đổi:
Nếu không muốn là 00001 mà chỉ là 1 và nếu không cho ra giá trị 0 thì làm như vầy đi:
PHP:
Function NumberSeparate(Text As String)
  a = Int(StrReverse(Val("1" & StrReverse(Text))) / 10)
  NumberSeparate = IIf(a = 0, "", a)
End Function

Nhưng không chính xác lắm, nếu là NGHIA0 thì lại cho giá trị ""

Vậy thì vòng lặp vậy, cho dù có cho ra giá trị là String thì đảm bảo được cấu trúc của số!

PHP:
Function TachSo(chuoi As String)
  Dim L As Long, kt
  For L = 1 To Len(chuoi)
    kt = Left(chuoi, 1)
    If Not IsNumeric(kt) Then chuoi = Replace(chuoi, kt, "")
  Next
  TachSo = chuoi
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
Mình lại đang phân vân, nếu mã số cho ra là NGHIA00001 thì nếu dùng Int(StrReverse(Val("1" & StrReverse(Text))) / 10) thì cho ra 1, nhưng lại muốn phải là 00001 thì không giải quyết được. Mặt khác, nếu text chỉ là NGHIA thì dùng dòng lệnh trên cho ra 0 mà thực tế, không có số 0 nào trong text. Cho nên phải thay đổi:
Nếu không muốn là 00001 mà chỉ là 1 và nếu không cho ra giá trị 0 thì làm như vầy đi:
PHP:
Function NumberSeparate(Text As String)
  a = Int(StrReverse(Val("1" & StrReverse(Text))) / 10)
  NumberSeparate = IIf(a = 0, "", a)
End Function

Nhưng không chính xác lắm, nếu là NGHIA0 thì lại cho giá trị ""

Vậy thì vòng lặp vậy, cho dù có cho ra giá trị là String thì đảm bảo được cấu trúc của số!

PHP:
Function TachSo(chuoi As String)
  Dim L As Long, kt
  For L = 1 To Len(chuoi)
    kt = Left(chuoi, 1)
    If Not IsNumeric(kt) Then chuoi = WorksheetFunction.Substitute(chuoi, kt, "")
  Next
  TachSo = chuoi
End Function
Không dùng vòng lặp cũng được mà bạn.
PHP:
Function TachSo(Str As String) As String
TachSo = Int(StrReverse(Val("1" & StrReverse(Str))) / 10)
If TachSo = 0 Or Len(TachSo) < Len(Str) - InStr(Str & 0, 0) + 1 Then
    TachSo = Right(Str, Len(Str) - InStr(Str & 0, 0) + 1)
End If
End Function
 
Upvote 0
Không dùng vòng lặp cũng được mà bạn.
PHP:
Function TachSo(Str As String) As String
TachSo = Int(StrReverse(Val("1" & StrReverse(Str))) / 10)
If TachSo = 0 Or Len(TachSo) < Len(Str) - InStr(Str & 0, 0) + 1 Then
    TachSo = Right(Str, Len(Str) - InStr(Str & 0, 0) + 1)
End If
End Function

Đâu bạn thử với dãy chuỗi này xem: huuthang_bd0010001000123456, hình như ra #VALUE! thì phải!
 
Lần chỉnh sửa cuối:
Upvote 0
Đâu bạn thử với dãy chuỗi này xem: huuthang_bd0010001000123456, hình như ra #VALUE! thì phải!
Thực hiện tính toán trên số phải có giới hạn, đâu phải muốn bao nhiêu số cũng được. Do mọi người đang bàn đến hàm Val chứ nếu không bạn dùng VBScript.RegExp là vô địch rồi. Khỏi vòng lặp chi hết.
PHP:
Function TachSo(Str As String) As String
With CreateObject("VBScript.RegExp")
    .Pattern = "\D*"
    TachSo = .Replace(Str, "")
End With
End Function
 
Upvote 0
Thực hiện tính toán trên số phải có giới hạn, đâu phải muốn bao nhiêu số cũng được. Do mọi người đang bàn đến hàm Val chứ nếu không bạn dùng VBScript.RegExp là vô địch rồi. Khỏi vòng lặp chi hết.
PHP:
Function TachSo(Str As String) As String
With CreateObject("VBScript.RegExp")
    .Pattern = "\D*"
    TachSo = .Replace(Str, "")
End With
End Function

Đây là đố tách số chứ không nói hàm Val.

Bài toán thì có nhiều giải pháp, nhưng kết quả chỉ có 1. Nếu bạn dùng giải pháp nào đó ngắn gọn, dễ hiểu, hiệu quả, nhanh chóng, chính xác, thì đó là giải pháp tốt nhất. Chứ nếu như chống chế bằng việc giới hạn thì tôi nghĩ giải pháp không đảm bảo.

Riêng cái Hàm của tôi thì đã không đúng ngay từ đầu vì đã sử dụng vòng lặp đối với tác giả ra đề, nhưng kết quả tuyệt đối đúng với cấu trúc TextNumber.
 
Upvote 0
Tô màu bất kỳ cho cell

Như ta đã biết, Excel chỉ cho phép tô 56 màu cho cell mà thôi. Trong khi với các objects, ta có thể tô khoảng 16 triệu màu khác nhau
Câu hỏi: Liệu ta có thể tô màu bất kỳ cho cell được không? (màu Button Face chẳng hạn)
 
Upvote 0
Màu bất kỳ (16 triệu màu) thì có: Setcolor.xls

Còn màu theo Window color set thì phải dùng Sys Color Class Control
 
Upvote 0
Màu bất kỳ (16 triệu màu) thì có: Setcolor.xls

Còn màu theo Window color set thì phải dùng Sys Color Class Control
Hổng đúng sư phụ ơi
Thử chỉnh Red = 236, Green = 233, Blue = 216 (chính là Button Face) rồi bấm Set sẽ thấy màu của Label ColorTest và màu của ActiveCell là hoàn toàn khác nhau (ActiveCell có màu vàng)
Ẹc... Ẹc...
 
Upvote 0
Màu bất kỳ (16 triệu màu) thì có: Setcolor.xls

Còn màu theo Window color set thì phải dùng Sys Color Class Control

Gán màu xuống cell thì có thể gán thoải mái nhưng khi nó thể hiện thì lại hoàn toàn khác với những gì ta muốn
Thế mới ĐỐ chứ sư phụ
(Sẽ rất khó nếu không biết dùng tiểu xảo và ngược lại... Hi... Hi...)
 
Upvote 0
Như ta đã biết, Excel chỉ cho phép tô 56 màu cho cell mà thôi. Trong khi với các objects, ta có thể tô khoảng 16 triệu màu khác nhau
Câu hỏi: Liệu ta có thể tô màu bất kỳ cho cell được không? (màu Button Face chẳng hạn)
Anh ơi, hình như câu hỏi này liên quan (hay tương tự) đến câu hỏi: "Làm sao đưa hình ảnh vào comment" ? (Ans: Fill Effects)

Lê Văn Duyệt
 
Upvote 0
Anh ơi, hình như câu hỏi này liên quan (hay tương tự) đến câu hỏi: "Làm sao đưa hình ảnh vào comment" ? (Ans: Fill Effects)

Lê Văn Duyệt
Không liên quan tí nào với Comment hay hình ảnh gì đâu Duyệt à. Chỉ tô màu bình thường vào cell thôi, có điều phải thêm 1 tí mánh
Thiết nghĩ trò này cũng có người từng làm nhưng không để ý đấy thôi
(thế nên mới đố vui: Giải pháp đơn giản nhưng khó nghĩ ra)
 
Upvote 0
Chào anh,

Vì theo em phân tích câu hỏi:
anhtuan66 đã viết:
Như ta đã biết, Excel chỉ cho phép tô 56 màu cho cell mà thôi.
Như vậy thì anh không thể làm gì ngoại trừ anh dùng "mẹo".

Còn ngược lại thì cách đặt vấn đề của anh sai.

Lê Văn Duyệt
 
Upvote 0
Chào anh,

Vì theo em phân tích câu hỏi:
Như vậy thì anh không thể làm gì ngoại trừ anh dùng "mẹo".
Còn ngược lại thì cách đặt vấn đề của anh sai.
Lê Văn Duyệt
Thì làm bất cứ cách gì có thể, miễn sao có thể TÔ MÀU ĐÚNG Ý MUỐN VÀO CELL thì thôi (cell thật sự chứ không phải hình ảnh hay Comment gì đâu nha)
Đương nhiên tôi tô được đàng hoàng thì mới đố chứ... Hi... hi...
Thật ra nói là "mẹo" thì cũng không hẳn. Chẳng qua là 1 cách ít người để ý thôi
--------------------------
Cái trò này nếu nói ra thì mọi người sẽ thấy nó đơn giản đến không ngờ. Thậm chí làm bằng tay còn được
 
Lần chỉnh sửa cuối:
Upvote 0
Thì làm bất cứ cách gì có thể, miễn sao có thể TÔ MÀU ĐÚNG Ý MUỐN VÀO CELL thì thôi (cell thật sự chứ không phải hình ảnh hay Comment gì đâu nha)
Đương nhiên tôi tô được đàng hoàng thì mới đố chứ... Hi... hi...
Thật ra nói là "mẹo" thì cũng không hẳn. Chẳng qua là 1 cách ít người để ý thôi
--------------------------
Cái trò này nếu nói ra thì mọi người sẽ thấy nó đơn giản đến không ngờ. Thậm chí làm bằng tay còn được
Có khi nào vẽ 1 textBox hình chữ nhật như cell, và fill màu 236,233,216 vào đó.
Làm "rừng thi làm vậy".
 
Upvote 0
Có khi nào vẽ 1 textBox hình chữ nhật như cell, và fill màu 236,233,216 vào đó.
Làm "rừng thi làm vậy".

Làm gì thì xin cứ tùy ý, miễn sao cái CELL THẬT SỰ PHẢI CÓ MÀU ĐÚNG Ý
Còn cách của tôi là không dùng bất cứ Object nào cả (tô màu bình thường)
Hi.. Hi...
---------------
Ở đây nói đến TÔ MÀU CHO CELL thì ngầm định phải hiểu rằng TÔ MÀU NỀN VÀ CẢ MÀU CHỮ
 
Upvote 0
Excel 2003 thì vô Option chỉnh 1 trong số 56 màu theo ý muốn.
Excel 2007 thì khỏi nói rồi.
 
Upvote 0
Ẹc ẹc, chỉnh trong option thì cần gì code?
Tool - Option - Color - Modify ...

ModifyColor.jpg
 
Lần chỉnh sửa cuối:
Upvote 0
Muốn code cũng có code:

PHP:
   ActiveWorkbook.Colors(15) = RGB(236, 233, 216)

Sau đó fill color hoặc font color bình thường bằng nút trên tool bar
 
Upvote 0
Muốn code cũng có code:

PHP:
   ActiveWorkbook.Colors(15) = RGB(236, 233, 216)

Sau đó fill color hoặc font color bình thường bằng nút trên tool bar
Code đầy đủ sẽ thế này:
PHP:
Sub Test()
  Dim Red As Long, Green As Long, Blue As Long
  Red = 236
  Green = 233
  Blue = 216
  ThisWorkbook.Colors(1) = RGB(Red, Green, Blue)
  Selection.Interior.Color = ThisWorkbook.Colors(1)
End Sub
-----------------------
Bởi vậy em mới nói, Anh Tuấn nói không rõ trong câu đố.
Lê Văn Duyệt
Đâu có gì mà không rõ hả Duyệt! Đã cho phép "dùng bất cứ cách nào" rồi còn gì. Miễn sao có thể tô màu và "nhìn thấy" đúng ý thì thôi
----------------------
Nói thêm rằng:
- Việc chỉnh màu trong Options chỉ có tác dụng đối với file hiện hành, các file khác không hề bị ảnh hưởng
- Để Reset lại màu chuẩn, dùng code: ThisWorkbook.ResetColors
 
Upvote 0
Ẹc Ẹc (bắt chước mấy anh...hi hi hi)

Câu đố kỳ này của anh không khó nhưng... em lại hiểu lầm...

Ban đầu em cũng viết code như vậy, nhưng em lại nghĩ, chẳng lẻ dễ như vậy à.

Lê Văn Duyệt
 
Upvote 0
Em có một câu đố khác.

Em có một dữ liệu gồm một vùng dữ liệu từ A1:D50. Hàng đầu tiên là tên trường dữ liệu (Mã vật tư| Tên vật tư| S.L| Đvt
Yêu cầu:
_ Sắp xếp vùng dữ liệu (sort) theo cột A.
_ Tính Subtotal ở cột C theo dữ liệu ở cột A.
_ Sau đó copy qua một sheet khác.
_ Chỉ dùng một dòng mã (one line code).

Lê Văn Duyệt
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Em có một câu đố khác.

Em có một dữ liệu gồm một vùng dữ liệu từ A1:D50. Hàng đầu tiên là tên trường dữ liệu (Mã vật tư| Tên vật tư| S.L| Đvt
Yêu cầu:
_ Sắp xếp vùng dữ liệu (sort) theo cột A.
_ Tính Subtotal ở cột C theo dữ liệu ở cột A.
_ Sau đó copy qua một sheet khác.
_ Chỉ dùng một dòng mã (one line code).

Lê Văn Duyệt
Nếu có thể được thì cho 1 file (giả lập) lên cho mọi người đở cực Duyệt ơi!
 
Upvote 0
Em có một câu đố khác.

Em có một dữ liệu gồm một vùng dữ liệu từ A1:D50. Hàng đầu tiên là tên trường dữ liệu (Mã vật tư| Tên vật tư| S.L| Đvt
Yêu cầu:
_ Sắp xếp vùng dữ liệu (sort) theo cột A.
_ Tính Subtotal ở cột C theo dữ liệu ở cột A.
_ Sau đó copy qua một sheet khác.
_ Chỉ dùng một dòng mã (one line code).

Lê Văn Duyệt

Cho em hỏi, Sort, gán công thức, copy ... đều là viết code hết phải không ạ?
 
Upvote 0
Chỉ có 1 cách duy nhất
1 câu lệnh duy nhất
Vừa sort
Vừa subtotal
vừa copy qua sheet khác

Đó là

Đọc sách lão chết tiệt
 
Upvote 0
Chỉ có 1 cách duy nhất
1 câu lệnh duy nhất
Vừa sort
Vừa subtotal
vừa copy qua sheet khác

Đó là

Đọc sách lão chết tiệt
Ngay từ đầu em cũng nghĩ sẽ dùng PivotTable, vì với PivotTable thì tự nó đã copy và cho subtotal rồi.... Có điều không biết có đúng ý của Duyệt hay không nữa
 
Upvote 0
Hic, vừa làm thử. Ít nhất 3 câu lệnh!
 
Upvote 0
Thầy viết bao nhiêu câu lệnh cũng được, miễn là 1 dòng (one line code) mà! thêm dấu : để cách dòng thôi hihihii
Bản thân 1 câu lệnh đã phải xuống 3 dòng, 3 câu lệnh mà không xuống dòng nó dài cả thước!
Chắc chắn làm vậy không phải là đáp án.
 
Upvote 0
Ngay từ đầu em cũng nghĩ sẽ dùng PivotTable, vì với PivotTable thì tự nó đã copy và cho subtotal rồi.... Có điều không biết có đúng ý của Duyệt hay không nữa

Mình có một vùng (~ mảng), vậy làm sao để tương tự như sau:
Mã:
Application.Thisworkbook.Worksheets("Sheet2").Range("A2").Paste[B][COLOR="red"] (2 công việc kia ở đây)[/COLOR][/B]

Lê Văn Duyệt
 
Upvote 0
Em có một câu đố khác.

Em có một dữ liệu gồm một vùng dữ liệu từ A1:D50. Hàng đầu tiên là tên trường dữ liệu (Mã vật tư| Tên vật tư| S.L| Đvt
Yêu cầu:
_ Sắp xếp vùng dữ liệu (sort) theo cột A.
_ Tính Subtotal ở cột C theo dữ liệu ở cột A.
_ Sau đó copy qua một sheet khác.
_ Chỉ dùng một dòng mã (one line code).

Lê Văn Duyệt
Lâu rồi mà chẳng thấy ai có ý kiến, thôi Duyệt giải luôn đi
 
Upvote 0
Câu đố về xử lý mảng

Tôi có 1 hàm thế này:
PHP:
Function JoinArray(ByVal sArray, ByVal Sep As String) As String
  Dim Item, TmpArr, Arr(), i As Long
  TmpArr = sArray
  For Each Item In TmpArr
    If Trim(CStr(Item)) <> "" Then
      ReDim Preserve Arr(i)
      Arr(i) = CStr(Item)
      i = i + 1
    End If
  Next
  If i Then JoinArray = Join(Arr, Sep)
End Function
Hàm này dùng để nối các phần tử của 1 mảng bất kỳ (ngoại trừ phần tử rổng) thành 1 chuổi với dấu phân cách cho trước
Ví dụ: Nối các phần tử trong vùng A1:B4 bằng công thức =JoinArray(A1:B4,", ")
Xem sơ qua thì dường như hàm không có vấn đề gì. Thế nhưng khi ta sửa tham chiếu thành 1 cell =JoinArray(A1,", ") thì hàm bị lỗi #VALUE!
Xin lỗi nguyên nhân và cách khắc phục?
 
Upvote 0
Tôi có 1 hàm thế này:
PHP:
Function JoinArray(ByVal sArray, ByVal Sep As String) As String
  Dim Item, TmpArr, Arr(), i As Long
  TmpArr = sArray
  For Each Item In TmpArr
    If Trim(CStr(Item)) <> "" Then
      ReDim Preserve Arr(i)
      Arr(i) = CStr(Item)
      i = i + 1
    End If
  Next
  If i Then JoinArray = Join(Arr, Sep)
End Function
Hàm này dùng để nối các phần tử của 1 mảng bất kỳ (ngoại trừ phần tử rổng) thành 1 chuổi với dấu phân cách cho trước
Ví dụ: Nối các phần tử trong vùng A1:B4 bằng công thức =JoinArray(A1:B4,", ")
Xem sơ qua thì dường như hàm không có vấn đề gì. Thế nhưng khi ta sửa tham chiếu thành 1 cell =JoinArray(A1,", ") thì hàm bị lỗi #VALUE!
Xin lỗi nguyên nhân và cách khắc phục?
Theo em thì khi tham chiếu là 1 cell thì tham chiếu đó không phải là mảng nên sẽ bị lỗi khi anh duyệt qua các phần tử của mảng. Cụ thể là lỗi ở dòng lệnh này:
PHP:
For Each Item In TmpArr
Vậy để khắc phục thì trước hết kiểm tra xem nó có phải là mảng không. Nếu không phải là mảng thì gán giá trị của tham chiếu vào kết quả và thoát Function luôn. Nếu không thì tiếp tục.
Em đề xuất sửa lại như thế này:
PHP:
Function JoinArray(ByVal sArray, ByVal Sep As String) As String
  Dim Item, TmpArr, Arr(), i As Long
  If Not IsArray(sArray) Then
    JoinArray = Trim(CStr(sArray))
    Exit Function
  End If
  TmpArr = sArray
  For Each Item In TmpArr
    If Trim(CStr(Item)) <> "" Then
      ReDim Preserve Arr(i)
      Arr(i) = CStr(Item)
      i = i + 1
    End If
  Next
  If i Then JoinArray = Join(Arr, Sep)
End Function
 
Upvote 0
Theo em thì khi tham chiếu là 1 cell thì tham chiếu đó không phải là mảng nên sẽ bị lỗi khi anh duyệt qua các phần tử của mảng. Cụ thể là lỗi ở dòng lệnh này:
PHP:
For Each Item In TmpArr
Vậy để khắc phục thì trước hết kiểm tra xem nó có phải là mảng không. Nếu không phải là mảng thì gán giá trị của tham chiếu vào kết quả và thoát Function luôn. Nếu không thì tiếp tục.
Em đề xuất sửa lại như thế này:
PHP:
Function JoinArray(ByVal sArray, ByVal Sep As String) As String
  Dim Item, TmpArr, Arr(), i As Long
  If Not IsArray(sArray) Then
    JoinArray = Trim(CStr(sArray))
    Exit Function
  End If
  TmpArr = sArray
  '...............
  '............
  If i Then JoinArray = Join(Arr, Sep)
End Function
Ngoài IsArray ra không biết còn cách khác không nhỉ?
Các bạn nghiên cứu xem!
 
Upvote 0
Lâu rồi mà chẳng thấy ai có ý kiến, thôi Duyệt giải luôn đi

Câu đố đã viết:
Em có một dữ liệu gồm một vùng dữ liệu từ A1:D50. Hàng đầu tiên là tên trường dữ liệu (Mã vật tư| Tên vật tư| S.L| Đvt
Yêu cầu:
_ Sắp xếp vùng dữ liệu (sort) theo cột A.
_ Tính Subtotal ở cột C theo dữ liệu ở cột A.
_ Sau đó copy qua một sheet khác.
_ Chỉ dùng một dòng mã (one line code).

Nếu phân tích câu hỏi ở trên thì chúng ta có 3 vấn đề cần giải quyết:
  1. Sắp xếp: bước này thường là bước đầu tiên trước khi tổng hợp.
  2. Subtotal: đây mới là bước tổng hợp và phải thực hiện sau bước thứ nhất.
  3. Xuất dữ liệu: đưa số liệu sau khi xử lý qua một vùng khác.
Đây là 3 bài toán chúng ta thường gặp trên diễn đàn và cũng là vấn đề em quan tâm "làm sao có một thủ tục (i.e một hàng code) để thực hiện các bước ở trên"

Nếu giải theo mẹo:
Learning_Excel đã viết:
Thầy viết bao nhiêu câu lệnh cũng được, miễn là 1 dòng (one line code) mà! thêm dấu : để cách dòng thôi hihihii
Rõ ràng cũng thỏa mãn yêu cầu.

Nếu giải một cách chính thống:
Rõ ràng như Bác ptm0412
ptm0412 đã viết:
Hic, vừa làm thử. Ít nhất 3 câu lệnh!
Rõ ràng, nó tương ứng với 3 vấn đề trên.
Vậy câu trả lời là: nếu không dùng một thủ tục tự viết thì không thể nào đạt được yêu cầu của bài toán ở trên (tính đến thời điểm hiện nay, vì biết đâu trong phiên bản sau M$ sẽ có một hàm/thủ tục để thực hiện điều đó).

Lê Văn Duyệt
 
Lần chỉnh sửa cuối:
Upvote 0
Ngoài IsArray ra không biết còn cách khác không nhỉ?
Các bạn nghiên cứu xem!
Anh thử kiểm tra phần tử mãng với hàm IsEmpty xem sao?

Mã:
Function JoinArray(ByVal sArray, ByVal Sep As String) As String
    Dim Item, TmpArr, Arr(), i As Long
    TmpArr = sArray
    For Each Item In TmpArr
        'If Trim(CStr(Item)) <> "" Then
        If Not IsEmpty(Item) Then
            ReDim Preserve Arr(i)
            Arr(i) = CStr(Item)
            i = i + 1
        End If
    Next
    If i Then JoinArray = Join(Arr, Sep)
End Function

Lê Văn Duyệt
 
Upvote 0
Anh thử kiểm tra phần tử mãng với hàm IsEmpty xem sao?

Mã:
Function JoinArray(ByVal sArray, ByVal Sep As String) As String
    Dim Item, TmpArr, Arr(), i As Long
    TmpArr = sArray
    For Each Item In TmpArr
        'If Trim(CStr(Item)) <> "" Then
        If Not IsEmpty(Item) Then
            ReDim Preserve Arr(i)
            Arr(i) = CStr(Item)
            i = i + 1
        End If
    Next
    If i Then JoinArray = Join(Arr, Sep)
End Function

Lê Văn Duyệt
Thí nghiệm hàm trên:
=JoinArray(A1,", ")
thì thấy vẫn còn lỗi mà Duyệt
 
Upvote 0
Ngoài IsArray ra không biết còn cách khác không nhỉ?
Các bạn nghiên cứu xem!
Nếu không dùng IsArray thì dùng bẫy lỗi. Em làm như thế này:
PHP:
Function JoinArray(ByVal sArray, ByVal Sep As String) As String
  Dim Item, TmpArr, Arr(), i As Long
  TmpArr = sArray
  On Error GoTo Err
  For Each Item In TmpArr
    If Trim(CStr(Item)) <> "" Then
      ReDim Preserve Arr(i)
      Arr(i) = CStr(Item)
      i = i + 1
    End If
  Next
  If i Then JoinArray = Join(Arr, Sep)
  Exit Function
Err:
  JoinArray = sArray
End Function
 
Upvote 0
Thí nghiệm hàm trên:
=JoinArray(A1,", ")
thì thấy vẫn còn lỗi mà Duyệt
Vậy ta có thể dùng hàm TypeName để kiểm tra kiểu của biến:
Mã:
Function UDF(Variable As Variant) As String
    UDF = TypeName(Variable)
End Function

Hàm TypeName sẽ trả về chuổi thông tin về biến. Không áp dụng cho kiểu người dùng.
Xin tham khảo tại đây.

Nhưng theo em nghĩ, đối với trường hợp này thì dùng hàm kiểm tra xem có phải mảng không là hợp lý nhất.

Lê Văn Duyệt
 
Lần chỉnh sửa cuối:
Upvote 0
Vâng! Chính xác là dùng On Error...TypeName = "Variant()"
Cái nào cũng được và đương nhiên khi dùng On Error... là khi ta đã thừa biết lỗi ấy là gì rồi (chứ không phải là bất chấp thủ đoạn)
----------------------
Không biết còn cái gì để đố nữa không đây? Hay là bạn Thắng và Duyệt nêu chủ đề gì đó xem
 
Upvote 0
Vâng! Chính xác là dùng On Error...TypeName = "Variant()"
Cái nào cũng được và đương nhiên khi dùng On Error... là khi ta đã thừa biết lỗi ấy là gì rồi (chứ không phải là bất chấp thủ đoạn)
----------------------
Không biết còn cái gì để đố nữa không đây? Hay là bạn Thắng và Duyệt nêu chủ đề gì đó xem
Những gì em biết đều học được từ GPE nên em đâu có cái gì mới, lạ để đố đâu.
 
Upvote 0
hi, mình vô tình làm như thế này mà nó cũng ra kết quả

Private Sub Button1_Click()
K = K + 1
Range("A1").Value = Range("a1").Value + K
End Sub
Nhờ các ace giải thích dùm!
hihi
 
Upvote 0
hi, mình vô tình làm như thế này mà nó cũng ra kết quả

Private Sub Button1_Click()
K = K + 1
Range("A1").Value = Range("a1").Value + K
End Sub
Nhờ các ace giải thích dùm!
hihi
Nếu không khai báo public biến K, khi bắt đầu chạy code, K = Nothing, chạy dòng lệnh K = K +1, K sẽ bằng 1.
Vậy sau mỗi lần chạy code, A1 sẽ = A1 + 1, và cứ thế tăng dần

Nghĩa là code trên tương tự:

PHP:
Private Sub Button1_Click()
    Range("A1").Value = Range("a1").Value + 1
End Sub

Khỏi cần biến K!
 
Upvote 0

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

Back
Top Bottom