Đố vui về VBA! (2 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
 
Mình có cái này muốn hỏi, nhưng thấy code đơn giản nên mạo phép đưa vào mục này cho các bạn mới theo luôn.

Sao code sau đây lại lỗi nhỉ, mục đích là điền công thức vào ô Ci?

HTML:
Sub Giai()
   Sheets("Huong Dan").Select
      For i = 3 To 6
         Range("c" & i).Formula = "A" & i + "b" & i
      Next i
End Sub

Nếu thay .Formula bằng .Value cũng lỗi luôn, thêm 02 ngoặc kép cũng lỗi luôn.
 
Upvote 0
Mình có cái này muốn hỏi, nhưng thấy code đơn giản nên mạo phép đưa vào mục này cho các bạn mới theo luôn.

Sao code sau đây lại lỗi nhỉ, mục đích là điền công thức vào ô Ci?

HTML:
Sub Giai()
   Sheets("Huong Dan").Select
      For i = 3 To 6
         Range("c" & i).Formula = "A" & i + "b" & i
      Next i
End Sub

Nếu thay .Formula bằng .Value cũng lỗi luôn, thêm 02 ngoặc kép cũng lỗi luôn.
Đây là câu hỏi chứ không phải câu đố, đã có một topic riêng dùng để giải thích, gỡ rối về code. Lần sau bạn nên post bài đúng chỗ.
Về câu hỏi của bạn, bạn sửa code lại thành như thế này thử xem sao:

PHP:
Sub Giai()
Sheets("Huong Dan").Select
      For i = 3 To 6
         Range("c" & i).Formula = "=A" & i & "+B" & i
      Next i
End Sub
Do bạn không giải thích gì hết nên tôi chỉ làm theo phán đoán cá nhân của tôi, có thể không đúng ý bạn.
 
Upvote 0
Xác định địa chỉ của vùng chứa Shape

Giả sử trên bảng tính tôi vẽ 1 Shape
Câu hỏi: Làm sao xác định được địa chỉ của vùng chứa Shape ấy

Capture.JPG
 
Lần chỉnh sửa cuối:
Upvote 0

File đính kèm

Upvote 0
Code VBA định dạng phân cách ngàn cho 1 vùng

Giả sử tôi có dữ liệu tại A1:A10 là number
Tôi muốn viết code để định dạng phân cách ngàn cho vùng này. Vậy xin hỏi tôi phải viết thế nào mới đúng?
Lưu ý rằng:
- Tôi chưa biết dấu phân cách ngàn trong Control Panel đang quy định thế nào
- Tôi cũng chưa biết mục "Use system separators" trong Excel Optionsđang check hay chưa
 
Upvote 0
Giả sử tôi có dữ liệu tại A1:A10 là number
Tôi muốn viết code để định dạng phân cách ngàn cho vùng này. Vậy xin hỏi tôi phải viết thế nào mới đúng?
Lưu ý rằng:
- Tôi chưa biết dấu phân cách ngàn trong Control Panel đang quy định thế nào
- Tôi cũng chưa biết mục "Use system separators" trong Excel Optionsđang check hay chưa
Theo em thì khi định dạng dấu phân cách hàng ngàn bằng Macro thì luôn luôn dùng dấu phẩy (,). Thiết lập của hệ thống hay của Excel không ảnh hưởng.
Code chỉ cần như thế này thôi.
Mã:
[A1:A10].NumberFormat = "#,#"
 
Upvote 0
Nạp giá trị cho 1 biến

Lấy 1 ví dụ:
Mã:
s = "[COLOR=#0000cd][B]Hello[/B][/COLOR]"
MsgBox s
Điều đương nhiên cái MsgBox ta nhận được là "Hello" rồi
Vậy xin hỏi: Có khi nào ta nạp giá trị cho 1 biến xong nhưng giá trị của biến ấy lại không đúng bằng với giá trị ban đầu hay không? (nạp vào là giá trị a nào đó nhưng MsgBox lại hiện kết quả là b)
Đương nhiên sau khi nạp xong giá trị cho biến thì MsgBox ngay, không thêm quá trình tính toán gì cả

Ẹc... Ẹc...
(câu này.. dễ nhỉ?)
 
Upvote 0
Lấy 1 ví dụ:
Mã:
s = "[COLOR=#0000cd][B]Hello[/B][/COLOR]"
MsgBox s
Điều đương nhiên cái MsgBox ta nhận được là "Hello" rồi
Vậy xin hỏi: Có khi nào ta nạp giá trị cho 1 biến xong nhưng giá trị của biến ấy lại không đúng bằng với giá trị ban đầu hay không? (nạp vào là giá trị a nào đó nhưng MsgBox lại hiện kết quả là b)
Đương nhiên sau khi nạp xong giá trị cho biến thì MsgBox ngay, không thêm quá trình tính toán gì cả

Ẹc... Ẹc...
(câu này.. dễ nhỉ?)
NDU đố VBA à? Thứ 7 lại ra vế đố thư giãn phải không?
 
Upvote 0
Lấy 1 ví dụ:
Mã:
s = "[COLOR=#0000cd][B]Hello[/B][/COLOR]"
MsgBox s
Điều đương nhiên cái MsgBox ta nhận được là "Hello" rồi
Vậy xin hỏi: Có khi nào ta nạp giá trị cho 1 biến xong nhưng giá trị của biến ấy lại không đúng bằng với giá trị ban đầu hay không? (nạp vào là giá trị a nào đó nhưng MsgBox lại hiện kết quả là b)
Đương nhiên sau khi nạp xong giá trị cho biến thì MsgBox ngay, không thêm quá trình tính toán gì cả

Ẹc... Ẹc...
(câu này.. dễ nhỉ?)
Có dùng Arr không Thầy?
 
Upvote 0
Cái này có được tính không?
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = [A1].Address Then
Application.EnableEvents = False
[A1] = [A1] * 5
Application.EnableEvents = True
End If
End Sub


Sub GPE()
Dim r As Range
Set r = [A1]
r = 5
MsgBox r
End Sub
 
Upvote 0
Mã:
Sub test()
Dim a As Long
a = "01"
MsgBox a
End Sub

Chú Tuấn không giới hạn luôn là có cho xài hàm hay khai báo biến không nhỉ. Nếu thể theo ý của chú thì kyo nghĩ là kyo gán vào a một chuỗi "01" và xuất ra msgbox là 1 chứ không phải là 01. Không biết vầy có được tính không?
 
Upvote 0
Nếu không cho tính toán ở Arr thì mình tạo 2 sub, sau đó gọi sub mình cần, hic

Mã:
Dim s As String
Sub s1()
    s = "Hello GPE"
    MsgBox s
End Sub

Sub s2()
    s = "Hello Giai Phap Excel"
    MsgBox s
End Sub

Sub Test()
    s1
    
End Sub
 
Upvote 0
Như thế này mà nhập thập phân vào nó cũng tự động đổi

Mã:
Sub th()
Dim m As Integer
m = InputBox("Nhap so")
MsgBox m
End Sub
 
Upvote 0
Chính xác là giống như kyo và anh sealand đã làm đấy. Tức:
- Khai báo biến là Long
- Gán biến = Số thập phân
- MsgBox chắc chắn không phải là số thập phân rồi
Có nghĩa là kiểu biến làm thay đổi giá trị của biến
---------------
Cái của anh LuânHai Lúa gọi là... ĂN GIAN
Ẹc... Ẹc...
 
Upvote 0
Chính xác là giống như kyo và anh sealand đã làm đấy. Tức:
- Khai báo biến là Long
- Gán biến = Số thập phân
- MsgBox chắc chắn không phải là số thập phân rồi
Có nghĩa là kiểu biến làm thay đổi giá trị của biến
---------------
Cái của anh LuânHai Lúa gọi là... ĂN GIAN
Ẹc... Ẹc...

Trong lập trình, tình huống giá trị của biến bị thay đổi ngoài tầm kiểm soát vẫn thường xảy ra - đặc biệt đối với các ngôn ngữ mà việc kiểm tra phép gán không chặt.
Với bài của NDU, tôi thì đang nghĩ tới hiệu ứng multi-task (đa nhiệm) -khi 1 tiến trình chưa kết thúc mà tiến trình kế tiếp đã được gọi thì cũng có thể xảy ra tình huống này (trong visual-fox hay gặp như thế); hoặc trong lập trình hướng đối tượng có thể xảy ra sự kiện thay đổi giá trị của biến một cách tự động...
Dẫu sao cũng có 1 thư giãn nho nhỏ cuối tuần!
 
Upvote 0
Trong lập trình, tình huống giá trị của biến bị thay đổi ngoài tầm kiểm soát vẫn thường xảy ra - đặc biệt đối với các ngôn ngữ mà việc kiểm tra phép gán không chặt.

Tôi nghĩ từ "đặc biệt" là không chính xác. Phải là "chỉ̉".
Bạn có thể gán được trong VBA nhưng với Delphi chẳng hạn thì bạn không gán được. Delphi không compile code như thế, nó báo lỗi ngay, chứ chưa nói tới chuyên chạy code.
Vd. khai biến a là Integer (4 bai, như VBA là Long) thì bạn không thể gán a = 1.0 chứ chưa nói tới chuyện gán a = 1.25
Trong VBA làm thế được vì VBA "cho phép" như thế

Với bài của NDU, tôi thì đang nghĩ tới hiệu ứng multi-task (đa nhiệm) -khi 1 tiến trình chưa kết thúc mà tiến trình kế tiếp đã được gọi

Tôi không rõ "multi-task" của bạn là gì nhưng nếu nói tới luồng - Thread - thì có những lúc code chạy sai. Nhưng sai là vì người lập trình làm ẩu, không kiểm soát được code của mình, không kiểm soát được các thread mình tạo ra.
Trong Windows có nhiều cơ cấu dùng để "đợi" vd. như WaitFor***, cơ cấu CreateEvent, SetEvent, ResetEvent v...v

hoặc trong lập trình hướng đối tượng có thể xảy ra sự kiện thay đổi giá trị của biến một cách tự động...

Nếu có thế thì là do code viết chưa chuẩn. Chứ làm gì có code chuẩn mà kết quả chạy nó phụ thuộc vào may rủi?
 
Upvote 0
Chuyển Sheet CodeName thành Sheet Name

Giả sử tôi có 3 sheet
- Sheet thứ nhất có tên là "Nguyễn" và Sheet CodeName là "S1"
- Sheet thứ hai có tên là "Anh" và Sheet CodeName là "S2"
- Sheet thứ ba có tên là "Tuấn" và Sheet CodeName là "S3"
-----------
Giờ ta gõ:
- Cell A1 chữ S1
- Cell A2 chữ S2
- Cell A3 chữ S3
Xin hỏi: Dùng code thế nào để:
- Kết quả tại B1 là Nguyễn
- Kết quả tại B2 là Anh
- Kết quả tại B3 là Tuấn
-------------
Tức biến đầu vào là Sheet CodeName (dạng String) và kết quả đầu ra là Sheet Name (dạng String)
 
Upvote 0
Giả sử tôi có 3 sheet
- Sheet thứ nhất có tên là "Nguyễn" và Sheet CodeName là "S1"
- Sheet thứ hai có tên là "Anh" và Sheet CodeName là "S2"
- Sheet thứ ba có tên là "Tuấn" và Sheet CodeName là "S3"
-----------
Giờ ta gõ:
- Cell A1 chữ S1
- Cell A2 chữ S2
- Cell A3 chữ S3
Xin hỏi: Dùng code thế nào để:
- Kết quả tại B1 là Nguyễn
- Kết quả tại B2 là Anh
- Kết quả tại B3 là Tuấn
-------------
Tức biến đầu vào là Sheet CodeName (dạng String) và kết quả đầu ra là Sheet Name (dạng String)

Vậy cũng được nè:
Mã:
Function ShName(ByVal shCodeName As String) As String
    Dim sh As Worksheet
    For Each sh In Sheets
        If sh.CodeName = shCodeName Then ShName = sh.Name
    Next
End Function
 
Upvote 0
Vậy cũng được nè:
Mã:
Function ShName(ByVal shCodeName As String) As String
    Dim sh As Worksheet
    For Each sh In Sheets
        If sh.CodeName = shCodeName Then ShName = sh.Name
    Next
End Function
Tạm chấp nhận
Tăng độ khó nha anh: Không dùng vòng để kiểm tra mà chuyển đổi trực tiếp luôn
Ẹc... Ẹc...
(Đố vui mà, đương nhiên phải có điểm khác biệt)
 
Upvote 0
Tạm chấp nhận
Tăng độ khó nha anh: Không dùng vòng để kiểm tra mà chuyển đổi trực tiếp luôn
Ẹc... Ẹc...
(Đố vui mà, đương nhiên phải có điểm khác biệt)
Sửa lại chút xíu như sau được không Thầy?

Mã:
Function ShName(ByVal shCodeName As String) As String
      ShName = ThisWorkbook.VBProject.vbcomponents(shCodeName).Properties("Name").Value

End Function
 
Upvote 0
Sửa lại chút xíu như sau được không Thầy?

Mã:
Function ShName(ByVal shCodeName As String) As String
      ShName = ThisWorkbook.VBProject.vbcomponents(shCodeName).Properties("Name").Value

End Function
Chính xác!
Hổng làm khó được Hai Lúa hen
(hổng ấy chú ra đề đi! Nguyên tắc là: lời giải ngắn gọn và độc đáo)
 
Upvote 0
Giả sử tôi có dữ liệu (như hình dưới).
Giờ người ta muốn trích lấy 1 vài cột nào đó sang sheet khác. Chẳng hạn muốn lấy các cột có tiêu đề sau: DATE, DEPT, MATERIAL NAME, QTY., AMOUNT(VND) ---> Tiếp theo đặt dữ liệu sang sheet khác và đổi luôn vị trí cột của kết quả thành MATERIAL NAME, DATE, DEPT, QTY., AMOUNT(VND)
Xin hỏi: Viết code thế nào là ngắn gọn nhất?
(dạo này diễn đàn lạ thật ---> Hổng biết phải Edit hình như thế nào nữa)

Capture.JPG
 

File đính kèm

Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Giả sử tôi có dữ liệu (như hình dưới).
Giờ người ta muốn trích lấy 1 vài cột nào đó sang sheet khác. Chẳng hạn muốn lấy các cột có tiêu đề sau: DATE, DEPT, MATERIAL NAME, QTY., AMOUNT(VND) ---> Tiếp theo đặt dữ liệu sang sheet khác và đổi luôn vị trí cột của kết quả thành MATERIAL NAME, DATE, DEPT, QTY., AMOUNT(VND)
Xin hỏi: Viết code thế nào là ngắn gọn nhất?
(dạo này diễn đàn lạ thật ---> Hổng biết phải Edit hình như thế nào nữa)
Mình tham gia đoạn code này :
Dim i As Long, j As Long
For i = 1 To 5
j = Choose(i, 4, 1, 2, 10, 12)
Sheet2.Columns(i).Value = Sheet1.Columns(j).Value
Next
 
Upvote 0
Dùng mảng: 1 mảng Source 1 mảng Result:

1 dòng lệnh đếm số dòng dữ liệu
1 dòng gán giá trị vào mảng Source,
1 dòng gán mảng kết quả xuống
1 vòng lặp ít nhất 5 dòng lệnh bên trong (= 7 dòng)

Tổng cộng 10 dòng. Ẹc ẹc
 
Upvote 0
Mình tham gia đoạn code này :
Dim i As Long, j As Long
For i = 1 To 5
j = Choose(i, 4, 1, 2, 10, 12)
Sheet2.Columns(i).Value = Sheet1.Columns(j).Value
Next

Sao bạn biết chắc các tiêu đề ấy nằm ở vị trí 1, 2, 4, 10 và 12?
Nói chung là truy xuất theo TÊN TIÊU ĐỀ và không biết nó nằm ở cột nào
(đương nhiên đã là đố vui thì giải pháp rất ngắn gọn)
 
Upvote 0
Giả sử tôi có dữ liệu (như hình dưới).
Giờ người ta muốn trích lấy 1 vài cột nào đó sang sheet khác. Chẳng hạn muốn lấy các cột có tiêu đề sau: DATE, DEPT, MATERIAL NAME, QTY., AMOUNT(VND) ---> Tiếp theo đặt dữ liệu sang sheet khác và đổi luôn vị trí cột của kết quả thành MATERIAL NAME, DATE, DEPT, QTY., AMOUNT(VND)
Xin hỏi: Viết code thế nào là ngắn gọn nhất?
(dạo này diễn đàn lạ thật ---> Hổng biết phải Edit hình như thế nào nữa)


Em dùng ADO thử, mặc dù đã cố gắng rút gọn, nhưng cũng còn dài thoòng.

Mã:
Sub FillList()
Dim cnn As New ADODB.Connection, lrs As New ADODB.Recordset, r As Integer
cnn.Open "Provider= Microsoft.Jet.OLEDB.4.0; data source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 8.0;"
With Sheet2
        lrs.Open "select [MATERIAL NAME], [DATE], [DEPT], [QTY#], [AMOUNT(VND)] From [Sheet1$]", cnn, 1, 3
        For i = 0 To (lrs.Fields.Count - 1)
            .Cells(1, i + 1) = lrs.Fields(i).Name
        Next
        .Range("A2").CopyFromRecordset lrs
    
End With
lrs.Close: Set lrs = Nothing: cnn.Close: Set cnn = Nothing
End Sub
 
Upvote 0
Mình nói thêm về bài toán này:
1> Đầu vào:
- Ta có dữ liệu nguồn, chẳng hạn là SrcRng = Sheet1.Range("A1:L10000")
- Tên các tiêu đề cần lấy cũng được cho trước, chẳng hạn là aTitle =Array("MATERIAL NAME","DATE","DEPT","QTY.","AMOUNT(VND)")
2> Đầu ra: Lọc sang sheet 2 với tên tiêu đề đã cho trong biến aTitle (và đúng theo thứ tự)
----------------------
Em dùng ADO thử, mặc dù đã cố gắng rút gọn, nhưng cũng còn dài thoòng.
Đao to búa lớn quá! Đố vui mà lị ---> Nó đâu có phức tạp đến vậy
Ẹc... Ẹc...
 
Upvote 0
Mình chỉnh lại đọan này :
Dim i As Long, k As String, j As Long
For i = 1 To 5
k = Choose(i, "MATERIAL NAME", "DATE", "DEPT", "QTY.", "AMOUNT(VND)")
j = WorksheetFunction.Match(k, Sheet1.[A1:Z1], 0)
Sheet2.Columns(i).Value = Sheet1.Columns(j).Value
Next
 
Upvote 0
Mình chỉnh lại đọan này :
Dim i As Long, k As String, j As Long
For i = 1 To 5
k = Choose(i, "MATERIAL NAME", "DATE", "DEPT", "QTY.", "AMOUNT(VND)")
j = WorksheetFunction.Match(k, Sheet1.[A1:Z1], 0)
Sheet2.Columns(i).Value = Sheet1.Columns(j).Value
Next

Aí chà chà!
Tạm được đi nhưng... KHÔNG VUI TÍ NÀO
Ẹc... Ẹc... nghĩ cách khác xem
(một giải pháp nói ra thì thấy dễ nhưng chưa nói thì... ít khi nghĩ đến)
 
Upvote 0
Mình tham gia thế này:

Mã:
Sub Test()
Dim i, aTitle(), Rg As Range
aTitle = Array("MATERIAL NAME", "DATE", "DEPT", "QTY.", "AMOUNT(VND)")
For i = 0 To UBound(aTitle)
If Rg Is Nothing Then Set Rg = Sheet1.UsedRange.Find(aTitle(i)).Resize(Sheet1.UsedRange.Rows.Count) _
Else Set Rg = Application.Union(Rg, Sheet1.UsedRange.Find(aTitle(i)).Resize(Sheet1.UsedRange.Rows.Count))
Next
Rg.Copy Sheet2.[A1]
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Hình như thứ tự cột chưa theo yêu cầu đề bài anh à.
 
Upvote 0
Bài toán trích lọc 1 vài cột trong toàn bộ dữ liệu chắc chắn có ứng dụng rất nhiều trong thực tế. Vậy không biết nếu phải làm bằng tay thì mọi người sẽ làm thế nào nhỉ?
(copy từng cột paste sang ta khỏi cần bàn đến đi)
Nghiaphuc biết chiêu này
 
Upvote 0
Bài toán trích lọc 1 vài cột trong toàn bộ dữ liệu chắc chắn có ứng dụng rất nhiều trong thực tế. Vậy không biết nếu phải làm bằng tay thì mọi người sẽ làm thế nào nhỉ?
(copy từng cột paste sang ta khỏi cần bàn đến đi)
Nghiaphuc biết chiêu này
Thường thì sẽ làm theo quy trình sau:
1. (double sheet) copy sang 1 sheet mới bằng cách Ctrl-Drag
2. (delete) Chọn các cột không để xóa 1 lần, hoặc xóa 1 cột sao đó chọn và nhấn F4 lặp lại lệnh...
3. (sort) Shift+Drag cột đến vị trí mong muốn
 
Upvote 0
Bài toán trích lọc 1 vài cột trong toàn bộ dữ liệu chắc chắn có ứng dụng rất nhiều trong thực tế. Vậy không biết nếu phải làm bằng tay thì mọi người sẽ làm thế nào nhỉ?
(copy từng cột paste sang ta khỏi cần bàn đến đi)
Nghiaphuc biết chiêu này
Có ai dùng "rừng" thế này?
Hay phải mảng trong mảng.
PHP:
Sub Macro1()
Dim i&, sTxt$
aTitle = Array("MATERIAL NAME", "DATE", "DEPT", "QTY.", "AMOUNT(VND)")
sTxt = Join(aTitle, vbBack)
Sheet1.Range("A1:L18").Copy Sheet2.Range("A1")
Sheet2.Select
Range("A1:L18").Value = Range("A1:L18").Value
For i = 12 To 1 Step -1
  If InStr(sTxt, Cells(1, i)) = 0 Then
    Columns(i).Delete Shift:=xlToLeft
  End If
Next i
End Sub
 
Upvote 0
Bài toán trích lọc 1 vài cột trong toàn bộ dữ liệu chắc chắn có ứng dụng rất nhiều trong thực tế. Vậy không biết nếu phải làm bằng tay thì mọi người sẽ làm thế nào nhỉ?
(copy từng cột paste sang ta khỏi cần bàn đến đi)
Nghiaphuc biết chiêu này
Đọc cái chỗ anh ndu ẩn đi kia mới nhớ. Khà khà... Em biết rồi. Hóa ra đây là chiêu anh ndu còn biết sau em. Ẹc ẹc...
 
Upvote 0
Có ai dùng "rừng" thế này?
Hay phải mảng trong mảng.
PHP:
Sub Macro1()
Dim i&, sTxt$
aTitle = Array("MATERIAL NAME", "DATE", "DEPT", "QTY.", "AMOUNT(VND)")
sTxt = Join(aTitle, vbBack)
Sheet1.Range("A1:L18").Copy Sheet2.Range("A1")
Sheet2.Select
Range("A1:L18").Value = Range("A1:L18").Value
For i = 12 To 1 Step -1
  If InStr(sTxt, Cells(1, i)) = 0 Then
    Columns(i).Delete Shift:=xlToLeft
  End If
Next i
End Sub
Hình như chưa đúng thứ tự
 
Upvote 0
Đọc cái chỗ anh ndu ẩn đi kia mới nhớ. Khà khà... Em biết rồi. Hóa ra đây là chiêu anh ndu còn biết sau em. Ẹc ẹc...

Thì học của chú mà...
Tuy cũng hổng phải cái gì ghê gớm nhưng ít ai biết (dù xài hoài) thì cũng xem như tuyệt chiêu rồi
Ẹc... Ẹc...
 
Upvote 0
Thì học của chú mà...
Tuy cũng hổng phải cái gì ghê gớm nhưng ít ai biết (dù xài hoài) thì cũng xem như tuyệt chiêu rồi
Ẹc... Ẹc...

Vậy được không:
Mã:
Sub doVui()
    Dim aTitle, SrcRng
    aTitle = Array("MATERIAL NAME", "DATE", "DEPT", "QTY.", "AMOUNT(VND)")
    Range("A1").Resize(, UBound(aTitle) + 1) = aTitle
    Set SrcRng = Sheet1.Range("A1:L10000")
    Worksheets(2).Range("A2").Resize(SrcRng.Rows.Count, UBound(aTitle) + 1) = "=HLOOKUP(Sheet2!R1C,Sheet1!R1C1:R1000C12,ROW(),0)"
    Worksheets(2).Range("A2").Resize(SrcRng.Rows.Count, UBound(aTitle) + 1) = Range("A2").Resize(SrcRng.Rows.Count, UBound(aTitle) + 1).Value
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Em lại làm như vầy:

PHP:
Sub ChuyenCot()
    Dim sArray As Variant, tittleArr As Variant, TransSheet As Variant
    Dim c As Long, h As Long, i As Long, j As Long, k As Long, r As Long, t As Long
    
    sArray = Sheet1.Range("A1:L18").Value
    tittleArr = Array("MATERIAL NAME", "DATE", "DEPT", "QTY.", "AMOUNT(VND)")
    
    t = UBound(tittleArr): c = 0
    h = UBound(sArray, 1): j = UBound(sArray, 2)
    
    ReDim TransSheet(1 To h, 1 To t + 1)
    For k = 0 To t
        For i = 1 To j
            If sArray(1, i) = tittleArr(k) Then
                c = c + 1
                For r = 1 To h
                    TransSheet(r, c) = sArray(r, i)
                Next
            End If
        Next
    Next
    Sheet2.Cells.Clear
    Sheet2.Range("A1").Resize(h, c).Value = TransSheet
End Sub
 
Upvote 0
hihi, em làm cách cùi bắp là copy roi chuyen cot.

PHP:
Sub Test()    
Sheet1.Range("A:A,B:B,D:D,J:J,L:L").Copy Sheets("Sheet2").Range("A1")    
Sheet2.Columns("C:C").Cut    
Sheet2.Columns("A:A").Insert Shift:=xlToRight
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Tác giả bảo là không bàn đến Copy mà!
 
Upvote 0
Khà khà... Đây mới gọi là "độc chiêu" nè:
PHP:
Sub Test()
    Sheet1.Activate
    [A1:E1].Value = Array("MATERIAL NAME", "DATE", "DEPT", "QTY.", "AMOUNT(VND)")
    Sheet2.UsedRange.AdvancedFilter xlFilterCopy, , [A1:E1]
End Sub
 
Upvote 0
Sao mình chạy báo lỗi '1004' dòng cuối nhỉ?

Vấn đề ở Sheet Name và SheetCodeName thôi anh à
Dùng tên sheet trên bảng tính cho chắc:
PHP:
Sub Test()
  Dim SrcRng As Range, rTitle As Range, aTitle
  Set SrcRng = Sheets("Sheet1").Range("A1:L10000")
  aTitle = Array("MATERIAL NAME", "DATE", "DEPT", "QTY.", "AMOUNT(VND)")
  Set rTitle = Sheets("Sheet2").Range("A1:E1")
  rTitle.Value = aTitle
  SrcRng.AdvancedFilter 2, , rTitle
End Sub
Chiêu này học được từ nghiaphuc cũng.. lâu lâu rồi
Advanced Filter mọi người xài nhiều nhưng chắc ít người biết nó có thể trích lọc theo 1 vài cột nào đó tùy ý người dùng chọn mà không cần phải lọc toàn bộ. Ngoài ra, nơi đặt kết quả cũng có thể đảo vị trí cột thoải mái
Ẹc... ẹc...
 
Lần chỉnh sửa cuối:
Upvote 0
Vấn đề ở Sheet Name và SheetCodeName thôi anh à
Dùng tên sheet trên bảng tính cho chắc:
PHP:
Sub Test()
  Dim SrcRng As Range, rTitle As Range, aTitle
  Set SrcRng = Sheets("Sheet1").Range("A1:L10000")
  aTitle = Array("MATERIAL NAME", "DATE", "DEPT", "QTY.", "AMOUNT(VND)")
  Set rTitle = Sheets("Sheet2").Range("A1:E1")
  rTitle.Value = aTitle
  SrcRng.AdvancedFilter 2, , rTitle
End Sub
Chiêu này học được từ nghiaphuc cũng.. lâu lâu rồi
Advanced Filter mọi người xài nhiều nhưng chắc ít người biết nó có thể trích lọc theo 1 vài cột nào đó tùy ý người dùng chọn mà không cần phải lọc toàn bộ. Ngoài ra, nơi đặt kết quả cũng có thể đảo vị trí cột thoải mái
Ẹc... ẹc...

Khoan đã, trong sheet1 nếu có 2 cột QTY. vậy theo đó, nó lấy cột nào?
 
Lần chỉnh sửa cuối:
Upvote 0
Khà khà... Đây mới gọi là "độc chiêu" nè:
PHP:
Sub Test()
    Sheet1.Activate
    [A1:E1].Value = Array("MATERIAL NAME", "DATE", "DEPT", "QTY.", "AMOUNT(VND)")
    Sheet2.UsedRange.AdvancedFilter xlFilterCopy, , [A1:E1]
End Sub

Hay, nếu vậy cần gì Sheet1.Activate chứ bạn NghiaPhuc!

PHP:
Sub Test2()
    Sheet2.[A1:E1].Value = Array("MATERIAL NAME", "DATE", "DEPT", "QTY.", "AMOUNT(VND)")
    Sheet1.UsedRange.AdvancedFilter xlFilterCopy, , Sheet2.[A1:E1]
End Sub
 
Upvote 0
Khoan đã, trong sheet1 nếu có 2 cột QTY. vậy theo đó, nó lấy cột nào?

Dùng công cụ có sẵn của bác Bill thì phải thuộc lòng câu này: CƠ SỞ DỮ LIỆU LUÔN LUÔN CHUẨN
Sao có thể có chuyện trùng tiêu đề được... Và nếu có, vui lòng làm sao cho nó hết trùng nếu muốn xài công cụ có sẵn (bằng không thì.. nghĩ xài)
Ẹc... Ẹc...
 
Upvote 0
Dùng công cụ có sẵn của bác Bill thì phải thuộc lòng câu này: CƠ SỞ DỮ LIỆU LUÔN LUÔN CHUẨN
Sao có thể có chuyện trùng tiêu đề được... Và nếu có, vui lòng làm sao cho nó hết trùng nếu muốn xài công cụ có sẵn (bằng không thì.. nghĩ xài)
Ẹc... Ẹc...

Hỏi là hỏi vậy, chứ biết chắc nó gặp cột đầu tiên sẽ "chụp liền". Có nhiều trường hợp trùng này lắm, chẳng hạn, ô A1:B1 (merge) là LOẠI HÀNG A, A2 là Số lượng, B2 là Thành tiền, cứ như thế cho đến n loại hàng.
 
Upvote 0
Hỏi là hỏi vậy, chứ biết chắc nó gặp cột đầu tiên sẽ "chụp liền". Có nhiều trường hợp trùng này lắm, chẳng hạn, ô A1:B1 (merge) là LOẠI HÀNG A, A2 là Số lượng, B2 là Thành tiền, cứ như thế cho đến n loại hàng.

Thôi thì mấy loại hằm bà lằng này ta khỏi bàn đến đi
Nếu "buộc" phải có loại tiêu đề dạng này, người ta cũng cố tạo thêm 1 dòng nữa là tiêu đề giả ---> Thế nhé
(chẳng ai lại muốn mang khổ vào mình)
Ẹc... Ẹc...
 
Upvote 0
Hay, nếu vậy cần gì Sheet1.Activate chứ bạn NghiaPhuc!
PHP:
Sub Test2()
    Sheet2.[A1:E1].Value = Array("MATERIAL NAME", "DATE", "DEPT", "QTY.", "AMOUNT(VND)")
    Sheet1.UsedRange.AdvancedFilter xlFilterCopy, , Sheet2.[A1:E1]
End Sub
Đâu có được đâu anh. Anh thử đứng ở sheet nguồn và chạy code xem nào! Theo em được biết thì tham số CopyToRange phải nằm trên sheet hiện hành mới được.
Mà anh ndu đưa ra file dữ liệu nghiệt thật, sheet có code name Sheet1 thì lại có tên là Sheet2 và ngược lại, đâm ra lại "loạn cào cào" lên, chẳng biết phải gọi cái nào là Sheet1, cái nào là Sheet2 nữa.
 
Upvote 0
Đâu có được đâu anh. Anh thử đứng ở sheet nguồn và chạy code xem nào! Theo em được biết thì tham số CopyToRange phải nằm trên sheet hiện hành mới được.
Mà anh ndu đưa ra file dữ liệu nghiệt thật, sheet có code name Sheet1 thì lại có tên là Sheet2 và ngược lại, đâm ra lại "loạn cào cào" lên, chẳng biết phải gọi cái nào là Sheet1, cái nào là Sheet2 nữa.

Sao vậy NghiaPhuc? mình gửi file lên nhé, kiểm tra lại đi, sheet nào mình cũng đặt nút lệnh và dùng chung một code hết đấy nhé!

Mã:
Sub Test2()
    [B]Sheet2.Cells.ClearContents[/B] [COLOR=#006400] '<---- Có thêm thì cũng chỉ thêm dòng này thôi.[/COLOR]
    Sheet2.[A1:E1].Value = Array("MATERIAL NAME", "DATE", "DEPT", "QTY.", "AMOUNT(VND)")
    Sheet1.UsedRange.AdvancedFilter xlFilterCopy, , [COLOR=#ff0000][B]Sheet2[/B][/COLOR].[A1:E1]
End Sub

Lỗi phát sinh là ở chỗ màu đỏ đấy, bạn không cho vào thì tèo.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Đâu có được đâu anh. Anh thử đứng ở sheet nguồn và chạy code xem nào! Theo em được biết thì tham số CopyToRange phải nằm trên sheet hiện hành mới được.
.
Làm bằng tay thì bắt buộc phải vậy, còn nếu dùng code thì không cần, chỉ cần ghi rõ vùng nào thuộc sheet nào là được rồi
Mà anh ndu đưa ra file dữ liệu nghiệt thật, sheet có code name Sheet1 thì lại có tên là Sheet2 và ngược lại, đâm ra lại "loạn cào cào" lên, chẳng biết phải gọi cái nào là Sheet1, cái nào là Sheet2 nữa.
Tại cố ý làm vậy đấy
Ai biểu dùng sheet code name chi! ---> Code của tôi luôn là Sheets("Tên sheet") cho chắc ---> Nếu người dùng tự ý đổi tên sheet thì đó là vấn đề của họ, không phải lỗi tại tôi
Ẹc... Ẹc...
 
Upvote 0
Sao vậy NghiaPhuc? mình gửi file lên nhé, kiểm tra lại đi, sheet nào mình cũng đặt nút lệnh và dùng chung một code hết đấy nhé!

Mã:
Sub Test2()
    [B]Sheet2.Cells.ClearContents[/B] [COLOR=#006400] '<---- Có thêm thì cũng chỉ thêm dòng này thôi.[/COLOR]
    [COLOR=#0000ff][B]Sheet2.[/B][/COLOR][A1:E1].Value = Array("MATERIAL NAME", "DATE", "DEPT", "QTY.", "AMOUNT(VND)")
    Sheet1.UsedRange.AdvancedFilter xlFilterCopy, , [COLOR=#ff0000][B]Sheet2[/B][/COLOR].[A1:E1]
End Sub
Lỗi phát sinh là ở chỗ màu đỏ đấy, bạn không cho vào thì tèo.
Em nhầm một chút, vấn đề không phải là ở chỗ màu đỏ mà là ở chỗ em quên chỗ màu xanh. Ẩu quá!
À, dòng lệnh anh thêm vào thì lại chẳng có ý nghĩa gì nếu thực sự Sheet2 chỉ sử dụng để lưu kết quả lọc. Kết quả này sẽ được anh chàng AdFi xóa tự động trước khi lấy kết quả mới. Nếu có thêm thì thêm Clear luôn chứ đừng ClearContents, vì Clear sẽ xóa tất cả mọi thứ (cả khung, màu nền,...), còn ClearContents chỉ xóa nội dung.
 
Upvote 0
Xác định tên của Workbook vừa mở

Giả sử các bạn tạo ra 1 Add-In có tên là Test.xla, trong Add-In này có 1 công đoạn xác định tên của Workbook nào đó vừa mở.
Ví dụ: (sau khi Add-In đã được kích hoạt)
- Tôi mở 1 workbook có tên là TestA.xls, lập tức 1 MsgBox xuất hiện với nội dung "Bạn vừa mở file TestA.xls"
- Tôi mở tiếp 1 workbook khác có tên là TestB.xls, lập tức 1 MsgBox xuất hiện với nội dung "Bạn vừa mở file TestB.xls"
Nói tóm lại: Cứ có Workbook nào được mở thì sẽ có thông báo xuất hiện cho biết tên của Workbook đó
Xin hỏi: Tôi phải viết code cho Add-In này như thế nào?
 
Upvote 0
Giả sử các bạn tạo ra 1 Add-In có tên là Test.xla, trong Add-In này có 1 công đoạn xác định tên của Workbook nào đó vừa mở.
Ví dụ: (sau khi Add-In đã được kích hoạt)
- Tôi mở 1 workbook có tên là TestA.xls, lập tức 1 MsgBox xuất hiện với nội dung "Bạn vừa mở file TestA.xls"
- Tôi mở tiếp 1 workbook khác có tên là TestB.xls, lập tức 1 MsgBox xuất hiện với nội dung "Bạn vừa mở file TestB.xls"
Nói tóm lại: Cứ có Workbook nào được mở thì sẽ có thông báo xuất hiện cho biết tên của Workbook đó
Xin hỏi: Tôi phải viết code cho Add-In này như thế nào?

Trường hợp với một cái file mới tạo từ Excel, thì sao ạ?
 
Upvote 0
Người ta đã bào là: TÊN FILE VỪA MỞ rồi mà
File vừa mở nghĩa là file có sẵn mình mở lên, khác với file vừa tạo mới nha

Đúng là không dễ nhai! Với addins nó chạy trước, sau đó mới mở workbook kích hoạt, bị báo lỗi chỗ này hoài!
 
Upvote 0
Giả sử các bạn tạo ra 1 Add-In có tên là Test.xla, trong Add-In này có 1 công đoạn xác định tên của Workbook nào đó vừa mở.
Ví dụ: (sau khi Add-In đã được kích hoạt)
- Tôi mở 1 workbook có tên là TestA.xls, lập tức 1 MsgBox xuất hiện với nội dung "Bạn vừa mở file TestA.xls"
- Tôi mở tiếp 1 workbook khác có tên là TestB.xls, lập tức 1 MsgBox xuất hiện với nội dung "Bạn vừa mở file TestB.xls"
Nói tóm lại: Cứ có Workbook nào được mở thì sẽ có thông báo xuất hiện cho biết tên của Workbook đó
Xin hỏi: Tôi phải viết code cho Add-In này như thế nào?


1. Ta làm một class để phục vụ các sự kiện của Application. Gọi là "CÁC" thôi chứ ta định phục vụ 1 sự kiện: WorkbookOpen.

Ta Insert 1 Class module và đặt tên vd. là clsAppEvents

Ta khai báo, "nộp đơn" là ta muốn phục vụ các sự kiện của Application:

Private WithEvents ExcelApp As Excel.Application

Trong cửa sổ code ở trên cùng có 2 combobox. Ta chọn Class ở combo bên trái rồi chọn Terminate ở combo bên phải, rồi nhập code: Set ExcelApp = Nothing
Ta chọn ExcelApp ở combo bên trái rồi chọn WorkbookOpen ở combo bên phải, rồi nhập code:
MsgBox "Ban vua mo file " & Wb.Name
Ta viết thêm sub SetExcelApp.

Toàn bộ code trong clsAppEvents:

Mã:
Private WithEvents ExcelApp As Excel.Application

Public Sub SetExcelApp(ByVal Excel As Excel.Application)
    Set ExcelApp = Excel
End Sub

Private Sub Class_Terminate()
    Set ExcelApp = Nothing
End Sub

Private Sub ExcelApp_WorkbookOpen(ByVal Wb As Workbook)
        MsgBox "Ban vua mo file " & Wb.Name
End Sub

2. Ta Insert Module1.
Code module1:

Mã:
Dim AppEvents As clsAppEvents

Private Sub Auto_Open()
    StartTrack
End Sub

Private Sub Auto_Close()
    StopTrack
End Sub

Sub StartTrack()
    Set AppEvents = New clsAppEvents 
    AppEvents.SetExcelApp Application
End Sub

Sub StopTrack()
    Set AppEvents = Nothing
End Sub

Nếu muốn các sự kiện khác thì chọn thêm.
 
Lần chỉnh sửa cuối:
Upvote 0
1. Ta làm một class để phục vụ các sự kiện của Application. Gọi là "CÁC" thôi chứ ta định phục vụ 1 sự kiện: WorkbookOpen.

Trời ơi!
Đố người có trình độ bằng em trở xuống thôi anh ơi
Anh mà vào cuộc thì.. lộ bí mật hết trơn rồi còn gì
Ẹc... Ẹc...
----------------
Thật ra em đang dự tính làm 1 Add-In xóa Style rác và xóa name rác (code của anh) với mục đích code sê chạy khi có bất cứ file nào đó mở lên. Đương nhiên phải có sự tham gia của Class để "bắt" sự kiện Open của 1 workbook nào đó rồi
 
Lần chỉnh sửa cuối:
Upvote 0
Trời ơi!
Đố người có trình độ bằng em trở xuống thôi anh ơi
Anh mà vào cuộc thì.. lộ bí mật hết trơn rồi còn gì
Ẹc... Ẹc...
----------------
Thật ra em đang dự tính làm 1 Add-In xóa Style rác và xóa name rác (code của anh) với mục đích code sê chạy khi có bất cứ file nào đó mở lên. Đương nhiên phải có sự tham gia của Class để "bắt" sự kiện Open của 1 workbook nào đó rồi

Chết thật, vô tình làm hỏng cuộc chơi của mọi người.
Từ sau viết rõ nhé. Là chỉ dành cho những người đã gửi ít nhất là 2000, 3000 bài trở lên.
 
Upvote 0
Chết thật, vô tình làm hỏng cuộc chơi của mọi người.
Từ sau viết rõ nhé. Là chỉ dành cho những người đã gửi ít nhất là 2000, 3000 bài trở lên.

Ác cái TRÌNH ĐỘ hổng phải dựa vào số bài gửi để phân định
Thôi thì thay vì giải đố, anh làm người RA ĐỀ đi, em thấy hay hơn
Ẹc... Ẹc...
 
Upvote 0
Ác cái TRÌNH ĐỘ hổng phải dựa vào số bài gửi để phân định
Thôi thì thay vì giải đố, anh làm người RA ĐỀ đi, em thấy hay hơn
Ẹc... Ẹc...

Đúng vậy đó! Em có hơn 3000 bài mà hết 1000 bài để hỏi, 1500 bài để tám + spam, còn lại mới trả lời à! Trình độ và số bài đôi khi là tỉ lệ nghịch! ẹc ... ẹc ...
 
Upvote 0
Ác cái TRÌNH ĐỘ hổng phải dựa vào số bài gửi để phân định
Thôi thì thay vì giải đố, anh làm người RA ĐỀ đi, em thấy hay hơn
Ẹc... Ẹc...

Khổ cái là tôi lười vô kể, vua lười mà.
Vì thế rất ít khi ngồi chơi cờ với ai đó do phải nghĩ liên tục mà. Nhưng ngồi ngoài "quân sư" thì lại thích vô cùng.
 
Upvote 0
Khổ cái là tôi lười vô kể, vua lười mà.
Vì thế rất ít khi ngồi chơi cờ với ai đó do phải nghĩ liên tục mà. Nhưng ngồi ngoài "quân sư" thì lại thích vô cùng.

Nếu Anh mà lười thì không ai siêng được cả! Nhìn các bài viết của Anh vừa trình bày rõ ràng, lập luận sâu sắc, code lại có phần diễn giải... Càng nhiều người mà "lười" như anh thì đỡ biết mấy!

Thêm:

Dạo này còn có phần "tếu tếu" giống giọng điệu của bác Concogia và ndu nữa! Có cảm giác như Mr.Okebap...
 
Lần chỉnh sửa cuối:
Upvote 0
Upvote 0
Lâu lâu mình tham gia đố vui một chút!

Chắc có lẽ là rất dễ với người đã biết kakaka.

Với Form, code đang chạy, ta bấm tổ hợp phím Ctrl+Pause (Break) sẽ làm cho code, form bị ngắt thủ tục, sẽ báo lỗi tạm ngưng thủ tục.

Vậy với phương thức nào hoặc thủ tục nào hoặc thuộc tính nào, dù cho bấm tổ hợp phím trên code hay form vẫn hoạt động bình thường!

Nào, chúng ta bắt đầu với file mẫu nhé!

Bấm nút Show Form trên sheet để form hiện ra, sau đó bấm Ctrl+Pause (Break) sẽ thấy nó ngưng hoạt động form. Thoát form, rồi tìm cách khống chế nó nhé!

Trả lời đúng đáp án và ngắn gọn (nếu có khác) thì sẽ được thưởng!

Ai trả lời đầu tiên sẽ được 2 chai sữa bắp từ Hoàng Trọng Nghĩa!

=================================================

Phương thức trả lời: KHÔNG GỬI LÊN ĐÂY!

Gửi Mail qua địa chỉ: NghiaCSG@yahoo.com

Đến hết ngày thứ hai, sáng ngày thứ ba tuần này, nếu ai có bài gửi mình sẽ post đáp án của người đó lên đây!

Tính thời gian theo thời gian của thư đã nhận nhé! Lưu ý nhớ đề nick của GPE nhé các bạn.

Tham gia cho vui nhé mọi người!
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Upvote 0
Đã gọi là CÙNG NHAU HỌC HỎI, giờ không gửi lên đây thì vui quỷ gì chứ

Vì có thưởng nên cho vui vậy thôi, chứ người nào gửi xong em cũng post lên bài của người đó à!

Thôi thì gửi đại lên đây đi, mail móc chi cho thêm mất công

Lẽ ra Hai Lúa Miền Tây không được tham gia, vì bài này ngày xưa chính Hai Lúa Miền Tây đã hướng dẫn cho mọi người về đề tài này, mình bổn cũ soạn lại. Hic hic.

Tại đây:

http://www.giaiphapexcel.com/forum/showthread.php?36694-Khoá-Ctrl-Break

(Vì đố vui nên bài này mình đã xóa phần code, chút trả lại nguyên bản)

Hai Lúa Miền Tây đã trả lời chính xác rồi đấy ạ! Mà theo nguyên tắc có được 2 chai sữa bắp không ta?
 

File đính kèm

  • DapAn.jpg
    DapAn.jpg
    60.4 KB · Đọc: 79
Lần chỉnh sửa cuối:
Upvote 0
Báo lỗi khi nhập không đúng mục trong list của ComboBox khi Exit khỏi nó.

Tôi nhớ đã rất lâu tôi có hỏi thuộc tính này tại diễn đàn mình, và được hướng dẫn như sau:

PHP:
Private Sub ComboBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
      If ComboBox1 = "" Then Exit Sub

      Dim i As Long
      
      For i = 0 To ComboBox1.ListCount - 1
            If ComboBox1.List(i) = ComboBox1 Then Exit For
      Next
      
      If i = ComboBox1.ListCount Then
            MsgBox "Ban chi duoc nhap muc co san trong list ma thoi!"
            Cancel = True
      End If
End Sub

Bây giờ tôi xin đố cũng với nội dung đó như sau:

ComboBox có thuộc tính MatchRequired, nếu chọn True thì khi đã Focus vào nó nếu gõ không đúng mục
trong list, thậm chí là xóa không có ký tự nào, khi Exit nó báo lỗi "Invalid Property Value" rất khó chịu.

Chúng ta đang cần là:

1) Nếu không gõ gì trong ComboBox thì Exit thoải mái.

2) Nếu gõ không đúng mục trong List thì khi Exit sẽ thông báo lỗi, dĩ nhiên bằng tiếng Việt (dù là không dấu) cho dễ hiểu.

ĐỐ BẠN:

Vậy bằng bất cứ sự kiện nào, thủ tục nào liên quan đến ComboBox ta sẽ thực hiện được 2 điều kiện trên, nếu không dùng vòng lặp For … Next càng tốt?

Thời gian của ai nhanh nhất người đó thắng!

Nói chung thủ tục này giống với thuộc tính MatchRequired=True, chỉ khác rỗng không báo lỗi và báo bằng msgbox của mình, thời gian thông báo như thuộc tính này (rất nhanh).

Nạp List hoặc nạp RowSource cho 2 ComboBox rồi thực hiện nhé (có sẳn nút lệnh nạp trên form)!

Dữ liệu là 1 cột và 65,536 dòng.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Các bạn ơi, hãy tham gia đi nhé! Bất cứ thành viên nào của diễn đàn mình!
 
Upvote 0
Các bạn ơi, hãy tham gia đi nhé! Bất cứ thành viên nào của diễn đàn mình!

Có phần thưởng gì không HTN?

Có chút nhiều nhiều thì tham gia cho xum tụ (nhớ đừng sữa bắp nữa - món phụ nữ quá và khó chuyển phát)

để bắt đầu tìm hiểu xem nào, form là khó nhai
-------------------
Hỏi thêm là luôn vào File đó ah, làm cả 2 combobox? làm sao đo thời gian đây?
 
Lần chỉnh sửa cuối:
Upvote 0
Có phần thưởng gì không HTN?

Có chút nhiều nhiều thì tham gia cho xum tụ (nhớ đừng sữa bắp nữa - món phụ nữ quá và khó chuyển phát)

để bắt đầu tìm hiểu xem nào, form là khó nhai
-------------------
Hỏi thêm là luôn vào File đó ah, làm cả 2 combobox? làm sao đo thời gian đây?

Lắm lúc tự mình tìm ra một nguyên tắc, một điều thú vị, một lối đi mới ... đó chính là phần thưởng của riêng mình, đó là niềm tự hào, có phải vậy không?

Chỉ thực hiện trên ComboBox1 thôi, chúng ta bỏ thủ tục Exit ban đầu và thay vào thủ tục của mình. Còn ComboBox2 chỉ là ví dụ để so sánh cách mà thuộc tính MatchRequied=True nó thực hiện như thế nào thôi. Mà có đo thời gian cho thằng này cũng chẳng biết đo nó ở đâu và như thế nào nữa, chỉ biết rằng khi mình thoát ra là ảnh báo lỗi liền, rất nhanh!
 
Upvote 0
Tham gia cho vui đi các bạn ơi, nếu không đúng đáp án cũng là học lẫn nhau là chính mà!

Nếu như không ai có đáp án, thì ngày mai mình tự "sướng" luôn vậy!
 
Upvote 0
Tham gia cho vui đi các bạn ơi, nếu không đúng đáp án cũng là học lẫn nhau là chính mà!

Nếu như không ai có đáp án, thì ngày mai mình tự "sướng" luôn vậy!

Vậy cụ thể là thế nào? Cái ComboBox mà ta xét có MatchRequired=True hay không? Triết lý của MatchRequired=True là cho tới tận khi ta không nhập dữ liệu khớp với 1 mục trong List thì ta sẽ nhận được thông báo "khó chịu" và không thoát được ComboBox. Bạn phàn nàn là thông báo "khó chịu" nhưng nhiệm vụ của MatchRequired=True là thế. Bạn thấy khó chịu và không chấp nhận được thì sao bạn lại chọn MatchRequired=True? Khi dữ liệu nhập là quan trọng cho kết quả cuối cùng thì tôi "bắt" người dùng phải nhập đúng bằng cách cho MatchRequired=True. Lúc đó thì người dùng có 2 lựa chọn: hoặc nhập đúng để đi tiếp hoặc nhấn nút "Hủy" mà tôi cung cấp để hủy quá trình nhập liệu / tính toán.
Tất nhiên tôi cũng có thể giải quyết theo cách khác. Tức MatchRequired=False nhưng trong Exit tôi kiểm tra dữ liệu nhập:
[GPECODE=vb]
If ComboBox1.ListIndex < 0 Then
If MsgBox("Ban chi duoc nhap muc co san trong list ma thoi!" & vbCrLf & _
"Hay chon OK de tro lai nhap du lieu hoac Cancel de huy nhap du lieu", _
vbOKCancel, "Error") = vbOK Then
Cancel = True
Else
' lenh huy nhap du lieu
End If
End If
[/GPECODE]
Bạn thấy là tôi kiểm tra dữ liệu mà không cần "phò phạch phe phẩy" gì cả (ôi cái thời xa xưa ấy ...).
----------------
Mỗi control được thiết kế với chủ ý nào đó. ComboBox dùng để nhập dữ liệu có trong List. Khả năng chọn từ List thay cho gõ "mệt nghỉ" chỉ là phụ mà thôi. Nếu dữ liệu là 1 trong các mục trong List thì dùng ComboBox là chuẩn vì nó được thiết kế cho việc như thế. Còn nếu có thể nhập dữ liệu bất kỳ thì dùng TextBox cho rồi.
Tất nhiên bạn có thể có nhu cầu là chấp nhận dữ liệu bất kỳ nhưng bạn vẫn có List sẵn để nếu người dùng muốn nhập cái có trong List thì tiết kiệm được thời gian công sức. Nhưng dù bạn dùng control nào thì cũng phải chấp nhận cách thức mà nó thao tác. Tương tự nếu bạn thiết lập thuộc tính nào thì cũng phải chấp nhận "hậu quả" của thiết lập đó. Không thể chọn công cụ A rồi phàn nàn là nó cứ thao tác như đã được thiết kế.
 
Lần chỉnh sửa cuối:
Upvote 0
Vậy cụ thể là thế nào? Cái ComboBox mà ta xét có MatchRequired=True hay không? Triết lý của MatchRequired=True là cho tới tận khi ta không nhập dữ liệu khớp với 1 mục trong List thì ta sẽ nhận được thông báo "khó chịu" và không thoát được ComboBox. Bạn phàn nàn là thông báo "khó chịu" nhưng nhiệm vụ của MatchRequired=True là thế. Bạn thấy khó chịu và không chấp nhận được thì sao bạn lại chọn MatchRequired=True? Khi dữ liệu nhập là quan trọng cho kết quả cuối cùng thì tôi "bắt" người dùng phải nhập đúng bằng cách cho MatchRequired=True. Lúc đó thì người dùng có 2 lựa chọn: hoặc nhập đúng để đi tiếp hoặc nhấn nút "Hủy" mà tôi cung cấp để hủy quá trình nhập liệu / tính toán.
Tất nhiên tôi cũng có thể giải quyết theo cách khác. Tức MatchRequired=False nhưng trong Exit tôi kiểm tra dữ liệu nhập:
[GPECODE=vb]
If ComboBox1.ListIndex < 0 Then
If MsgBox("Ban chi duoc nhap muc co san trong list ma thoi!" & vbCrLf & _
"Hay chon OK de tro lai nhap du lieu hoac Cancel de huy nhap du lieu", _
vbOKCancel, "Error") = vbOK Then
Cancel = True
Else
' lenh huy nhap du lieu
End If
End If
[/GPECODE]
Bạn thấy là tôi kiểm tra dữ liệu mà không cần "phò phạch" gì cả.
----------------
Mỗi control được thiết kế với chủ ý nào đó. ComboBox dùng để nhập dữ liệu có trong List. Khả năng chọn từ List thay cho gõ "mệt nghỉ" chỉ là phụ mà thôi. Nếu dữ liệu là 1 trong các mục trong List thì dùng ComboBox là chuẩn vì nó được thiết kế cho việc như thế. Còn nếu có thể nhập dữ liệu bất kỳ thì dùng TextBox cho rồi.
Tất nhiên bạn có thể có nhu cầu là chấp nhận dữ liệu bất kỳ nhưng bạn vẫn có List sẵn để nếu người dùng muốn nhập cái có trong List thì tiết kiệm được thời gian công sức. Nhưng dù bạn dùng control nào thì cũng phải chấp nhận cách thức mà nó thao tác. Tương tự nếu bạn thiết lập thuộc tính nào thì cũng phải chấp nhận "hậu quả" của thiết lập đó. Không thể chọn công cụ A rồi phàn nàn là nó cứ thao tác như đã được thiết kế.

Thật ra em nói khó chịu ở đây với thuộc tính đó là như vầy: Nếu mình không nhập gì trong ComboBox đó nó cũng báo lỗi. Thứ 2 là mình muốn Việt hóa cái MsgBox của nó chứ tất cả các thông báo bằng tiếng Việt, tự nhiên nó "chọt" vô một câu tiếng Anh lạ hoắc, thà là làm chương trình toàn tiếng Anh thì không nói làm gì!

Đương nhiên là có những ComboBox mình nhập thoải mái những gì cần nhập, và có những cái mình chỉ muốn nhập vào cái danh sách sẳn có thôi.

Về đáp án:

Phải công nhận, Thầy làm rất đúng với đáp án của em! Quá xuất sắc! Đúng là bậc Thầy của những Thầy!


Từ câu đố này, em muốn mọi người thấy nó rất là dễ mà đôi khi mình nghĩ sao cao siêu quá! Và rằng bẫy lỗi cũng có những lỗi nhìn thấy trước ví dụ như phép chia không được chia cho 0. Nhưng có những lỗi ta lợi dụng lỗi để bẫy lỗi như bài này. Nói lỗi là như vầy, khi ta chọn thuộc tính MatchEntry = MatchEntryComplete thì khi ta gõ bất cứ thứ gì nó theo sự kiện Change mà dò tìm ListIndex, nếu nó không tìm thấy gì thì trả về lỗi không tìm thấy (lúc này ListIndex = -1) vì thế, ta lợi dụng điểm này để bẫy lỗi là như vậy!

Nhưng phải chú ý sẽ báo lỗi hoàn toàn sai khi ta gõ vào cho dù ta gõ từng chữ một đúng với nội dung của từng mục thì nó vẫn báo lỗi nếu ta chọn MatchEntry = MatchEntryNone, chỉ khi nó được chọn trực tiếp trên List xổ ra mới không bị lỗi mà thôi.

Cám ơn Thầy đã tham gia!
 
Lần chỉnh sửa cuối:
Upvote 0
Mỗi control được thiết kế với chủ ý nào đó. ComboBox dùng để nhập dữ liệu có trong List. Khả năng chọn từ List thay cho gõ "mệt nghỉ" chỉ là phụ mà thôi. Nếu dữ liệu là 1 trong các mục trong List thì dùng ComboBox là chuẩn vì nó được thiết kế cho việc như thế. Còn nếu có thể nhập dữ liệu bất kỳ thì dùng TextBox cho rồi.
Tất nhiên bạn có thể có nhu cầu là chấp nhận dữ liệu bất kỳ nhưng bạn vẫn có List sẵn để nếu người dùng muốn nhập cái có trong List thì tiết kiệm được thời gian công sức. Nhưng dù bạn dùng control nào thì cũng phải chấp nhận cách thức mà nó thao tác. Tương tự nếu bạn thiết lập thuộc tính nào thì cũng phải chấp nhận "hậu quả" của thiết lập đó. Không thể chọn công cụ A rồi phàn nàn là nó cứ thao tác như đã được thiết kế.

Cũng nói rõ là cái ComboBox vì em thích dùng nó như kiểu MatchRequired=True này, nhưng lại không thích kiểu báo lỗi của nó nên em đã chọn MatchRequired=False và nó thực hiện giống tính chất của MatchRequired=True.

Bạn thấy là tôi kiểm tra dữ liệu mà không cần "phò phạch phe phẩy" gì cả (ôi cái thời xa xưa ấy ...).

Bởi thế, em mới "mào" cái For ... Next ban đầu vào để đánh lạc hướng người giải đố để "nhức đầu" một tí mà! hheheheheh.

Nhưng phải chú ý sẽ báo lỗi hoàn toàn sai khi ta gõ vào cho dù ta gõ từng chữ một đúng với nội dung của từng mục thì nó vẫn báo lỗi nếu ta chọn MatchEntry = MatchEntryNone, chỉ khi nó được chọn trực tiếp trên List xổ ra mới không bị lỗi mà thôi.


Kể cả ComboBox khi ta chọn thuộc tính MatchRequired=True thì nó cũng gặp như trường hợp này!
 
Lần chỉnh sửa cuối:
Upvote 0
Vẫn còn cách khác mà không phải là sử dụng mẹo - không theo đường chính như cách đó,

Vậy các bạn thử tìm xem,

hong biết là theo kiểu sau có được không anh?

If ... Then
ComboBox2.MatchRequired = False
Else
ComboBox2.MatchRequired = True
End If
 
Upvote 0
Vẫn còn cách khác mà không phải là sử dụng mẹo - không theo đường chính như cách đó,

Vậy các bạn thử tìm xem,

Lời giải của bải tôi đã đố chỉ đơn giản như thế này:
PHP:
Private Sub ComboBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    If ComboBox1 = "" Or ComboBox1.ListIndex > -1 Then Exit Sub
    MsgBox "Ban chi duoc nhap muc co san trong list ma thoi!"
    Cancel = True
End Sub

Tuy nhiên, để thử làm cái mà bạn đố tiếp theo, tôi cũng cố thử như sau:

Tạo một biến Boolean bên ngoài, bẫy lỗi tại sự kiện Change, rồi theo biến Boolean "bắt lỗi" ở sự kiện Exit:

PHP:
Dim isErr As Boolean

Private Sub ComboBox1_Change()
    isErr = False
    On Error GoTo ErrCase
    Dim BienAo As String
    BienAo = ComboBox1.List(, 0)
    Exit Sub
ErrCase:
    isErr = True
End Sub

Private Sub ComboBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    If ComboBox1 = "" Or isErr = False Then Exit Sub
    MsgBox "Ban chi duoc nhap muc co san trong list ma thoi!"
    Cancel = True
End Sub

Xem ra nó cũng na ná cái kia.
 
Upvote 0
Vẫn còn cách khác mà không phải là sử dụng mẹo - không theo đường chính như cách đó,

Vậy các bạn thử tìm xem,

@Nghĩa:
Nghĩa cứ tôi bạn, anh em là được. Tôi đã từng yêu cầu ai đó đừng gọi là Thầy. Nếu có khâu "nhận trò" thì lúc đó là quan hệ Thầy - Trò còn không thì chia sẻ lẫn nhau thôi.
Thực ra tôi không phải là Thầy ... bói để đoán được đáp án của Nghĩa. Cũng chả phải là Thầy do qua trường lớp, vì 1 khóa ngắn hạn về lập trình cũng chưa học.
--------------
Tôi cũng không bói được đáp án của vodoi2x, nhưng nếu viết khác đi thì cũng có thể thế này, nếu tôi không lầm:

[GPECODE=vb]
If Not ComboBox1.MatchFound Then
If MsgBox("Ban chi duoc nhap muc co san trong list ma thoi!" & vbCrLf & _
"Hay chon OK de tro lai nhap du lieu hoac Cancel de huy nhap du lieu", _
vbOKCancel, "Error") = vbOK Then
Cancel = True
Else
' lenh huy nhap du lieu
End If
End If
[/GPECODE]
 
Lần chỉnh sửa cuối:
Upvote 0
@Nghĩa:
Nghĩa cứ tôi bạn, anh em là được. Tôi đã từng yêu cầu ai đó đừng gọi là Thầy. Nếu có khâu "nhận trò" thì lúc đó là quan hệ Thầy - Trò còn không thì chia sẻ lẫn nhau thôi.
Thực ra tôi không phải là Thầy ... bói để đoán được đáp án của Nghĩa. Cũng chả phải là Thầy do qua trường lớp, vì 1 khóa ngắn hạn về lập trình cũng chưa học.
--------------
Tôi cũng không bói được đáp án của vodoi2x, nhưng nếu viết khác đi thì cũng có thể thế này, nếu tôi không lầm:

[GPECODE=vb]
If Not ComboBox1.MatchFound Then
If MsgBox("Ban chi duoc nhap muc co san trong list ma thoi!" & vbCrLf & _
"Hay chon OK de tro lai nhap du lieu hoac Cancel de huy nhap du lieu", _
vbOKCancel, "Error") = vbOK Then
Cancel = True
Else
' lenh huy nhap du lieu
End If
End If
[/GPECODE]

Đúng rùi, bác siwtom ah, đó mới chính là thuộc tính (.MatchFound)sinh ra để kiểm tra việc tồn tại của item đó hay không.

Dùng đúng chức năng từ công cụ thuộc tính sẵn có thì sẽ giúp code đơn giản và ưu thế về tốc độ.

Qua đây mới thấy Microsoft đã dự trù khá nhiều trường hợp và thật là kiến trúc tư duy có hệ thống có khác - hơn hẳn kiểu tư duy chắp vá vụ vặt như chúng ta
 
Upvote 0
@Nghĩa:
Nghĩa cứ tôi bạn, anh em là được. Tôi đã từng yêu cầu ai đó đừng gọi là Thầy. Nếu có khâu "nhận trò" thì lúc đó là quan hệ Thầy - Trò còn không thì chia sẻ lẫn nhau thôi.
Thực ra tôi không phải là Thầy ... bói để đoán được đáp án của Nghĩa. Cũng chả phải là Thầy do qua trường lớp, vì 1 khóa ngắn hạn về lập trình cũng chưa học.

Thầy kính quý,

Không phải ai em cũng nhận họ làm Sư phụ, làm Thầy, không phải người mà em đóng tiền học phí để đứng trên bục giảng thì trong lòng em tôn trọng là thầy mà tại vì họ là ông thầy.

Nhưng như em đã từng ghi trong chữ ký của em:

Ba người cùng đi, tất có người là Thầy ta: lựa cái hay của người này mà học, xét cái quấy của người kia mà tự sửa mình

Với bề dầy và sâu về kiến thức thì em đã học hỏi được ở Thầy rất là nhiều, thông qua đó em đã cải thiện được kiến thức mình nhiều hơn.

Vẫn biết chúng ta không có gì để ràng buộc tình nghĩa Thầy-Trò, nhưng trong tâm em thì em vẫn xem Thầy là Thầy của em ạ.

Chúc Thầy có nhiều sức khỏe và tặng thêm cho diễn đàn nhiều kiến thức bổ ích để những người còn kém cỏi như em được học thêm ạ.

Cám ơn Thầy vì tất cả.
 
Upvote 0
Code chuyển từ number sang Date

- Tôi có dữ liệu dạng number tại cột A
- Mỗi cell là 1 số có 8 chữ số
- Số được bố trí nhìn giống như dạng yyyymmdd. Ví dụ: 20130103, 20130104
- Tôi viết code để chuyển những số này thành Date. Ví dụ 20130103 sẽ được chuyển thành 3/1/2013
Code như sau:
Mã:
Sub Number2Date()
  Dim rng, rCel As Range, lTmp
  Dim lR As Long, lC As Long
  On Error Resume Next
  Set rng = Selection
  If TypeOf rng Is Range Then
    For Each rCel In rng
      lTmp = rCel.Value
      If IsNumeric(lTmp) Then
        If Val(lTmp) > 100000 Then
          lTmp = DateValue(Format(lTmp, "0000""/""00""/""00"))
          rCel.Value = lTmp
        End If
      End If
    Next
    rng.NumberFormat = "dd/mm/yyyy"
    MsgBox "Done!"
  End If
End Sub
Code chạy không có vấn đề nhưng nếu 1 cell nào đó được định dạng trước là dd/mm/yyyy thì code không có tác dụng.
Nói chung, nếu cell được định dạng General thì code chạy không có vấn đề
Xin hỏi: Phải giải quyết vấn đề này thế nào?
(Mời xem file để biết thêm chi tiết)
 

File đính kèm

Upvote 0
- Tôi có dữ liệu dạng number tại cột A
- Mỗi cell là 1 số có 8 chữ số
- Số được bố trí nhìn giống như dạng yyyymmdd. Ví dụ: 20130103, 20130104
- Tôi viết code để chuyển những số này thành Date. Ví dụ 20130103 sẽ được chuyển thành 3/1/2013
Code như sau:
Mã:
Sub Number2Date()
  Dim rng, rCel As Range, lTmp
  Dim lR As Long, lC As Long
  On Error Resume Next
  Set rng = Selection
  If TypeOf rng Is Range Then
    For Each rCel In rng
      lTmp = rCel.Value
      If IsNumeric(lTmp) Then
        If Val(lTmp) > 100000 Then
          lTmp = DateValue(Format(lTmp, "0000""/""00""/""00"))
          rCel.Value = lTmp
        End If
      End If
    Next
    rng.NumberFormat = "dd/mm/yyyy"
    MsgBox "Done!"
  End If
End Sub
Code chạy không có vấn đề nhưng nếu 1 cell nào đó được định dạng trước là dd/mm/yyyy thì code không có tác dụng.
Nói chung, nếu cell được định dạng General thì code chạy không có vấn đề
Xin hỏi: Phải giải quyết vấn đề này thế nào?
(Mời xem file để biết thêm chi tiết)

Nếu ô được định dạng ngày thì khi dùng .value để lấy giá trị kết quả sẽ là ngày. Trong dữ liệu của anh, các ô được định dạng ngày trước không hiển thị được do vượt quá giới hạn. Khi dùng .value lấy giá trị các ô này sẽ bị lỗi.

Vậy nên theo em thì anh dùng .value2 thay cho .value thì sẽ ổn.

Trích nguyên văn trong Help của Excel
The only difference between this property and the Value property is that the Value2 property doesn’t use the Currency and Date data types. You can return values formatted with these data types as floating-point numbers by using the Double data type.
 
Upvote 0
Đổi font size và tô màu cho text trong Label

Tôi vẽ 1 Label (thuộc Forms Control) trên Sheet
Ta thừa biết object này không thể đổi được font size hay font color gì cả
Vậy mà tôi đã làm được


Capture.JPG



Các bạn mở file xem và cho biết: Tôi đã làm điều đó như thế nào?
Ẹc... ẹc...
 

File đính kèm

Upvote 0
Tôi vẽ 1 Label (thuộc Forms Control) trên Sheet
Ta thừa biết object này không thể đổi được font size hay font color gì cả
Vậy mà tôi đã làm được


View attachment 96280



Các bạn mở file xem và cho biết: Tôi đã làm điều đó như thế nào?
Ẹc... ẹc...

Em làm như đoạn clip ở dưới, hong biết còn cách nào nữa không Thầy.

[video=youtube;Vgt4YQkVaSk]http://www.youtube.com/watch?v=Vgt4YQkVaSk&amp;feature=youtu.be[/video]
 
Upvote 0
Upvote 0
Rất có lý! Nhưng sao trong file của tôi, cái Label ấy không giống với cái Label mà Hai Lúa đang làm? (chẳng có công thức liên kết)
Ẹc... Ẹc...

Vậy là còn ít nhất 1 cách nữa, cách này không dùng cell phụ, phải dùng code phải không Thầy?
 
Upvote 0
Rất có lý! Nhưng sao trong file của tôi, cái Label ấy không giống với cái Label mà Hai Lúa đang làm? (chẳng có công thức liên kết)
Ẹc... Ẹc...
Thì thêm 1 bước nữa là chọn Label và xóa công thức trên Formula bar là được. Bây giờ thì cứ việc xóa ô A1 đi cũng chẳng sao.
 
Upvote 0
Vậy là còn ít nhất 1 cách nữa, cách này không dùng cell phụ, phải dùng code phải không Thầy?

Ai mà biết đâu nè
Cách gì cũng được, miễn sao ra kết quả Y CHANG như file của tôi là được rồi
Nói chung, cách của Hai Lúa hoàn toàn chấp nhận được, chỉ là "thiếu" 1 chút, vì chẳng lẽ khi cái Label đi đâu cũng phải "mang theo" cell phụ sao?
------------------------
Đất nước nghèo kiết xác như Bắc Triều Tiên cũng ráng bắn 1 phát tên lửa, vậy mà Hai Lúa còn xài Excel 2003 hen?
 
Upvote 0
Ai mà biết đâu nè
Cách gì cũng được, miễn sao ra kết quả Y CHANG như file của tôi là được rồi
Nói chung, cách của Hai Lúa hoàn toàn chấp nhận được, chỉ là "thiếu" 1 chút, vì chẳng lẽ khi cái Label đi đâu cũng phải "mang theo" cell phụ sao?
------------------------
Đất nước nghèo kiết xác như Bắc Triều Tiên cũng ráng bắn 1 phát tên lửa, vậy mà Hai Lúa còn xài Excel 2003 hen?

Nghĩa Phúc đã trả lời đúng câu hỏi của Thầy rồi phải không. Nghĩa Phúc nhanh tay thật.

---------------------
Hic, thật ra em cũng đang sử dụng 2010 ở máy cá nhân cho kịp thời đại, 2003 là máy cơ quan nên đành chịu.
 
Upvote 0
Thì thêm 1 bước nữa là chọn Label và xóa công thức trên Formula bar là được. Bây giờ thì cứ việc xóa ô A1 đi cũng chẳng sao.

Nghĩa Phúc đã trả lời đúng câu hỏi của Thầy rồi phải không. Nghĩa Phúc nhanh tay thật.
Nghe qua thì rất có lý, nhưng nên biết rằng topic này là BÀN VỀ VBA, tức là VIẾT CODE
Làm bằng tay xem như đã thông qua, vậy chúng ta viết code thế nào để ra được kết quả như vậy?
Chắc là các bạn sẽ nghĩ: Ôi, dễ ẹc, đã làm bằng tay được thì record macro sẽ có code --->Thì cứ thử đi rồi biết! (đố mà gán được công thức vào Label đấy!)
Tóm lại: Khi nào có code, cứ đưa lên đây để kiểm chứng
Ẹc... Ẹc...
 
Upvote 0
Nghe qua thì rất có lý, nhưng nên biết rằng topic này là BÀN VỀ VBA, tức là VIẾT CODE
Làm bằng tay xem như đã thông qua, vậy chúng ta viết code thế nào để ra được kết quả như vậy?
Chắc là các bạn sẽ nghĩ: Ôi, dễ ẹc, đã làm bằng tay được thì record macro sẽ có code --->Thì cứ thử đi rồi biết! (đố mà gán được công thức vào Label đấy!)
Tóm lại: Khi nào có code, cứ đưa lên đây để kiểm chứng
Ẹc... Ẹc...

Ghi macro thì thấy nó dùng macro4 (ExecuteExcel4Macro) nhưng ghi cho đã rồi gán ngược lại không được!
 
Upvote 0
Thì có KHÓ mới ĐỐ chứ
Nhưng đã là ĐỐ VUI thì giải pháp luôn rất đơn giản
Cố lên. Ẹc... Ẹc...

Hic, thử đủ các cách, nào là Formula, FormularR1C1, LinkCell v.v... làm ráo trọi, code không báo lỗi gì cả, nhưng kết quả không như ý!

Nhức đầu quá, thôi để cao thủ khác có cao kiến, mình đành đứng ngoài cuộc! Công nhận lâu lâu Thầy có những câu đố thật độc đáo!
 
Upvote 0

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

Back
Top Bottom