Cách thêm kí tự vào đầu dòng ?

Liên hệ QC

Nguyen Rem

Tất cả chỉ là đưa ra quyết định đúng đắn
Tham gia
23/2/22
Bài viết
211
Được thích
30
Giới tính
Nữ
Em chào các anh chị ^^ . Cũng lâu lắm rồi không đăng bài nhưng mà thôi em không dài dòng đâu :>
Hiện tại em đang có một số khó khăn trong quá trình viết code mong các anh chị cùng giúp em khắc phục nhé :

Vấn đề:
Bình thường em đều viết từ vựng tiếng anh qua một file excel:
1659968433086.png
Em đã từng làm một cái phím tắt trên excel , nó được gán với một macro (marco này được viết và lưu ở một file excel khác Hiện tại nó có tên là "character.xlsm") .
1659968639919.png
Nó dùng với chức năng là thêm kí tự "." vào đầu dòng cái ô của mình đang chọn:
Ví dụ:
1659968800731.png
Nhưng nó không được thông minh cho lắm ^^ (Các anh chị vào module thứ nhất của file "character.xlsm" để xem và chạy thử code) . Nói đến đây mong là các anh chị hiểu vấn đề em đang gặp phải :)))
Code:
1659969088174.png

Minh họa cho thứ đang muốn làm
Ví dụ 1:

1659969280178.png
Lúc để chuột vào một dòng bất kì nào đó trong một ô và nhấn một phím tắt (phím tắt này do mình thiết lập sẵn) thì code sẽ phân tích xem các kí tự nào cùng thuộc một dòng trong ô đó thì nó sẽ thêm kí tự "." vào đầu dòng của dòng đó (Chú ý con chuột trong các bức hình --Nó được giữ nguyên vị trí sau khi nhấn "phím tắt"--)
Kết quả mong muốn:
1659969620046.png

Ví dụ 2:
1659970440055.png
Kết quả mong muốn:
1659969563442.png

Em cảm ơn mọi người đã dành thời gian đọc hết đến đây --Nó thực sự dài-- . Rất mong nhận được sự hỗ trợ từ mọi người ^^
 

File đính kèm

  • 1659969514585.png
    1659969514585.png
    7.2 KB · Đọc: 9
  • E(08-08-2022).xlsx
    9.7 KB · Đọc: 1
  • character.xlsm
    14.8 KB · Đọc: 3
Lần chỉnh sửa cuối:
Dim oCell as range
Set oCell = activeCell
If vba.len(oCell.value2) > 0 then
oCell.value = "." & vba.Replace(oCell.value2, vba.chrw$(10), Vba.chrw$(10) & "." )
Else
'...
End if
 
Upvote 0
Dim oCell as range
Set oCell = activeCell
If vba.len(oCell.value2) > 0 then
oCell.value = "." & vba.Replace(oCell.value2, vba.chrw$(10), Vba.chrw$(10) & "." )
Else
'...
End if
Em cảm ơn anh nhiều ạ ^^ . Vấn đề thật đơn giản, cơ mà em nghĩ phức tạp quá :>
 
Upvote 0
Dim oCell as range
Set oCell = activeCell
If vba.len(oCell.value2) > 0 then
oCell.value = "." & vba.Replace(oCell.value2, vba.chrw$(10), Vba.chrw$(10) & "." )
Else
'...
End if
Nhưng mà anh ơi !
Anh cho em hỏi cái từ khóa "VBA" ở trong code của anh nó là gì thế ạ ? Em tra trên "microsoft documentaion" cũng không có thấy( Hoặc là em tra từ khóa không đúng) . Anh cung cấp cho em cái từ khóa hoặc link đọc với . Em cảm ơn anh nhiều !
 
Upvote 0
Nhưng mà anh ơi !
Anh cho em hỏi cái từ khóa "VBA" ở trong code của anh nó là gì thế ạ ? Em tra trên "microsoft documentaion" cũng không có thấy( Hoặc là em tra từ khóa không đúng) . Anh cung cấp cho em cái từ khóa hoặc link đọc với . Em cảm ơn anh nhiều !
Tìm kiếm thông tin ở mức căn bản bạn cũng chưa biết thì học gì.

helpvba.png


VBA là tên module - thư viện Visual Basic For Application thôi

Tools -> References - 1

View -> Object Browser - 2

vba.png

Vd. Nếu trong Module1 bạn có sub Test thì có 2 cách gọi:
1. Test
2. Module1.Test - cách gọi tường minh.

Nhiều khi cả 2 cách gọi đều được nhưng có những trường hợp chỉ có cách gọi tường minh 2 được phép. Suy nghĩ lôgíc là hiểu ngay thôi. Giả sử trong project còn có module khác mà trong đó cũng có sub Test. Lúc này dùng cách 1 thì cụ tổ của thánh cũng chịu không biết bạn định gọi sub Test nào. Chắc chắn lúc này gọi Test sẽ có lỗi. Bắt buộc phải là Module1.Test hoặc Module2.Test tùy theo bạn muốn gọi sub nào. Có nhiều tình huống gọi vd. MID(...) được nhưng đôi lúc VBE thông báo lỗi mà chỉ có cách gọi tường minh VBA.MID mới thành công.
 
Upvote 0
Tìm kiếm thông tin ở mức căn bản bạn cũng chưa biết thì học gì.

View attachment 279742


VBA là tên module - thư viện Visual Basic For Application thôi

Tools -> References - 1

View -> Object Browser - 2

View attachment 279743

Vd. Nếu trong Module1 bạn có sub Test thì có 2 cách gọi:
1. Test
2. Module1.Test - cách gọi tường minh.

Nhiều khi cả 2 cách gọi đều được nhưng có những trường hợp chỉ có cách gọi tường minh 2 được phép. Suy nghĩ lôgíc là hiểu ngay thôi. Giả sử trong project còn có module khác mà trong đó cũng có sub Test. Lúc này dùng cách 1 thì cụ tổ của thánh cũng chịu không biết bạn định gọi sub Test nào. Chắc chắn lúc này gọi Test sẽ có lỗi. Bắt buộc phải là Module1.Test hoặc Module2.Test tùy theo bạn muốn gọi sub nào. Có nhiều tình huống gọi vd. MID(...) được nhưng đôi lúc VBE thông báo lỗi mà chỉ có cách gọi tường minh VBA.MID mới thành công.
Em cảm ơn anh nhiều ạ ^^ Tại lúc thấy từ khóa VBA được dùng em có kiểm tra xem liệu nó là object hay method hay property ở trên trang microsoft documentaion . Nhưng em bấm xem toàn bộ các object , property và method của từng object thì đều không có thấy , cơ mà đại ý của em là em có tra nhưng mà không thấy :))) nên em hỏi lại (hình ở dưới là chỗ em tra thông tin --Cái Object Model ấy anh --)
1659982950282.png
Còn phần giải thích của anh ở phần sau em đã đọc rồi ạ ^^ . Nếu có gì mà không rõ thì em lại hỏi anh sau :> . Em cảm ơn anh nhiều
 
Upvote 0
Những điều sau đây tôi đã chỉ dẫn một vài lần rồi, cách đây mấy năm.

Đôi lúc trong một Project có vài hàm bị trùng tên.
Gặp trường hợp này, cách dễ nhất để phân biệt hàm cần gọi là gọi theo tiền tố chỉ định thư viện hoặc Module chứa hàm ấy.
VBA là thư viện chính của các hàm trong VBA.
VBA.Len(...) là lệnh gọi hàm Len, xác định là hàm Len của VBA, không phải vất vưởng nào khác.
Bình thường thì tiền tố VBA là mặc định cho tất cả các hàm của VBA. Tức là Len(chuoi) tương đương với VBA.Len(chuoi)

Giả sử ở ModuleX nào đó tôi có đặt một hàm trùng tên với hàm sẵn có:
Public Function Mid(s)
Mid = (Len(s)+1) \ 2
End Function
Thì trong tầm vực của Project hiện tại, hàm Mid của tôi sẽ chồng lên hàm Mid căn bản của VBA. Và lệnh gọi Mid sẽ gọi hàm của tôi. Muốn gọi hàm căn bản, tôi bắt buộc phải dùng tiền tố VBA.

Tiền tố VBA này còn được dùng vào công việc xác định rằng hàm được gọi là hàm "gin", sẽ không chịu ảnh hưởng của môi trường đang vận hành (như Options,...)
Ví dụ điển hình (và khá quan trọng):
VBA.Array(...) bảo đảm rằng mảng tạo ra sẽ bắt đầu bằng chỉ số 0, không chịu ảnh hưởng của lệnh Option Base 1/0.
 
Upvote 0
Tìm kiếm thông tin ở mức căn bản bạn cũng chưa biết thì học gì.

View attachment 279742


VBA là tên module - thư viện Visual Basic For Application thôi

Tools -> References - 1

View -> Object Browser - 2

View attachment 279743

Vd. Nếu trong Module1 bạn có sub Test thì có 2 cách gọi:
1. Test
2. Module1.Test - cách gọi tường minh.

Nhiều khi cả 2 cách gọi đều được nhưng có những trường hợp chỉ có cách gọi tường minh 2 được phép. Suy nghĩ lôgíc là hiểu ngay thôi. Giả sử trong project còn có module khác mà trong đó cũng có sub Test. Lúc này dùng cách 1 thì cụ tổ của thánh cũng chịu không biết bạn định gọi sub Test nào. Chắc chắn lúc này gọi Test sẽ có lỗi. Bắt buộc phải là Module1.Test hoặc Module2.Test tùy theo bạn muốn gọi sub nào. Có nhiều tình huống gọi vd. MID(...) được nhưng đôi lúc VBE thông báo lỗi mà chỉ có cách gọi tường minh VBA.MID mới thành công.
Anh ơi ! Hiện tại em đã Tạm viết xong cái macro mà em muốn rồi(có thể vẫn lỗi gì đó) nhưng mà em có một câu hỏi muốn hỏi anh :
1660004092104.png
Tại sao mà lúc mình comment bỏ cái dòng em bôi đỏi thì tại cái dòng em khoanh màu xanh nó lại bị lỗi "Subcript out of range" ạ . Lúc sáng em loay hoay mãi mới phát hiện ra nhưng không hiểu tại sao nói lại lỗi như thế(code em ghi tại Module1 của file "character.xlsm") . Mong anh giúp em giải thích . Em cảm ơn anh nhiều ^^
 

File đính kèm

  • character.xlsm
    18.5 KB · Đọc: 6
Upvote 0
Anh ơi ! Hiện tại em đã Tạm viết xong cái macro mà em muốn rồi(có thể vẫn lỗi gì đó) nhưng mà em có một câu hỏi muốn hỏi anh :
View attachment 279747
Tại sao mà lúc mình comment bỏ cái dòng em bôi đỏi thì tại cái dòng em khoanh màu xanh nó lại bị lỗi "Subcript out of range" ạ . Lúc sáng em loay hoay mãi mới phát hiện ra nhưng không hiểu tại sao nói lại lỗi như thế(code em ghi tại Module1 của file "character.xlsm") . Mong anh giúp em giải thích . Em cảm ơn anh nhiều ^^
Thôi tôi hướng dẫn bạn mặc dù bạn cũng biết cần tìm ở đâu: hãy gõ trong google vba redim rồi đọc khi nào chán thì thôi.

À mà bạn học về khai báo biến mảng rồi chứ nhỉ? Có những loại mảng nào, và bộ nhớ dành cho chúng được phân chia khi nào?
 
Lần chỉnh sửa cuối:
Upvote 0
Bỏ cái for i đi.
For each oCell in selection
là xong rồi.
Tuy nhiên, trên bảng tính selection có thể là objects, shapes, images...nên cần cẩn trọng.
 
Upvote 0
Sao đọc tới đọc lui tôi vẫn không hiểu cái ý vị trí con trỏ chuột nhỉ.
Code ở bài 1: Thông thường người ta sẽ lưu đối tượng vào biến, khi cần chỉ cần gọi biến, đâu phải lúc nào cũng là Workbooks(1)
Ngoài ra còn phải xử lý trường hợp dữ liệu đã chuẩn rồi chạy code thêm lần nữa lại thành sai.
 
Upvote 0
Thôi tôi hướng dẫn bạn mặc dù bạn cũng biết cần tìm ở đâu: hãy gõ trong google vba redim rồi đọc khi nào chán thì thôi.

À mà bạn học về khai báo biến mảng rồi chứ nhỉ? Có những loại mảng nào, và bộ nhớ dành cho chúng được phân chia khi nào?
Dạ vâng ạ ! Để em đọc lại rồi sẽ tiếp tục thảo luận với anh sau ạ ^^
Bỏ cái for i đi.
For each oCell in selection
là xong rồi.
Tuy nhiên, trên bảng tính selection có thể là objects, shapes, images...nên cần cẩn trọng.
Đúng thật là em tư duy hơi rắc rối thật ^^ . Em cảm ơn anh nhiều ạ
Bài đã được tự động gộp:

Sao đọc tới đọc lui tôi vẫn không hiểu cái ý vị trí con trỏ chuột nhỉ.
À cái này ! Kiểu em đang học về cái phần mềm autohotkey ấy anh . Nên em muốn hướng người giúp em nếu được thì code của họ có nói đến cái con trỏ chuột(để tiện thể học luôn) . Tại kiểu em nghĩ có thể dùng bàn phím thay vì con trỏ chuột ấy :))) (Em mới học nên kiểu chỉ đoán lung tung thôi tại em cũng hay tò mò nên là cũng hay đoán ).
Code ở bài 1: Thông thường người ta sẽ lưu đối tượng vào biến, khi cần chỉ cần gọi biến, đâu phải lúc nào cũng là Workbooks(1)
Em cũng đang muốn làm như thế nhưng mà chưa biết làm thế nào ấy anh . Nếu được thì anh giúp em đoạn đó với . Hiện tại em vẫn chưa có ý tưởng gì cả :>
Ngoài ra còn phải xử lý trường hợp dữ liệu đã chuẩn rồi chạy code thêm lần nữa lại thành sai.
Em vẫn chưa thực sự hiểu câu này! Anh có thể nói kĩ hơn giúp em được không ?
 
Upvote 0
Em cũng đang muốn làm như thế nhưng mà chưa biết làm thế nào ấy anh . Nếu được thì anh giúp em đoạn đó với . Hiện tại em vẫn chưa có ý tưởng gì cả :>
Đoạn code bên dưới tôi minh họa cho việc dùng biết đối tượng, bạn có làm gì đi nữa thì rTarget vẫn là vùng chọn ban đầu khi code được gọi.
Mã:
Set rTarget = Selection
[A1].Select
Workbooks.Open ("...")
Workbooks(i).Activate
Debug.Print rTarget.Address(External:=True)
Em vẫn chưa thực sự hiểu câu này! Anh có thể nói kĩ hơn giúp em được không ?
Bạn thử gọi thủ tục nhiều hơn 1 lần với cùng một ô rồi xem kết quả sẽ hiểu tôi muốn nói gì.
 
Upvote 0
Upvote 0
Kệ em đó đi, em í đang học. Từ từ thôi, nhiều thứ quá hơi chóng mặt á.
Thấy bảo không hiểu ý bác Hữu Thắng nên em nói cho hiểu thôi, chứ nếu viết để sử dụng thì ứng dụng vào là thấy ngay vấn đề thôi anh
 
Upvote 0
Là nếu có dấu chấm rồi, bấm thêm có dấu chấm nữa ấy mà. Code phải xét có dấu chấm hay chưa mới thực hiện lệnh chứ
Vậy phải thêm TH lỡ có 2 dấu chấm có cần sửa lại 1 không ? :D
Có • hay không thì quất thêm mấy cái and trong đó nữa là được.
Bài đã được tự động gộp:

Thôi tôi hướng dẫn bạn mặc dù bạn cũng biết cần tìm ở đâu: hãy gõ trong google vba redim rồi đọc khi nào chán thì thôi.

À mà bạn học về khai báo biến mảng rồi chứ nhỉ? Có những loại mảng nào, và bộ nhớ dành cho chúng được phân chia khi nào?
Cơ mà chổ này để bạn đó đọc Redim em thấy nó chưa nổi bật lắm.
Tại sao mà lúc mình comment bỏ cái dòng em bôi đỏi thì tại cái dòng em khoanh màu xanh nó lại bị lỗi "Subcript out of range" ạ . Lúc sáng em loay hoay mãi mới phát hiện ra nhưng không hiểu tại sao nói lại lỗi như thế(code em ghi tại Module1 của file "character.xlsm") . Mong anh giúp em giải thích . Em cảm ơn anh nhiều ^^
Chỗ này
PHP:
Sub SpecialCharacter()
'Workbooks.Open ("E:\EXCEL\VBA\character.xlsm")
Dim i As Integer
Dim oCell As Range
Dim ArrRng As Range
'ReDim ArrRng(1 To Selection.Areas.Count)

Application.Workbooks(1).Activate
With Workbooks(1)

For i = 1 To Selection.Areas.Count
    Set ArrRng = .Worksheets(1).Range(Selection.Areas(i).Address(False, False))
    For Each oCell In ArrRng
            If VBA.Len(oCell.Value) > 0 And VBA.InStr(oCell.Value, ChrW$(10)) <> 0 Then
                oCell.Value = "•" & Replace(oCell.Value, ChrW$(10), ChrW$(10) & "•")
            End If
    Next
Next
End With

Workbooks("character.xlsm").Close

End Sub

Thuần duyệt qua 2 Range cho dễ hiểu :D
 
Lần chỉnh sửa cuối:
Upvote 0
Vậy phải thêm TH lỡ có 2 dấu chấm có cần sửa lại 1 không ? :D
Chắc là không nên, chức năng của nó là thêm • đầu mỗi dòng chứ không phải là sửa dữ liệu ban đầu đi, nếu dữ liệu có như vậy thì viết thêm cái khác xử lý nó
Có • hay không thì quất thêm mấy cái and trong đó nữa là được.
Thực ra cũng không cần xét nữa, xử lý replace luôn cho nhanh gọn
 
Upvote 0
Góp ý chút về vụ bố trí, quản lý.
Theo mình bạn nên xác định cái đối tượng ban đầu định mang nó ra xử là gì ?
Xong mang nó ra để xử, hết thì đóng lại, thay vì "E:\EXCEL\VBA\character.xlsm" ; bên dưới Workbooks("character.xlsm").Close thì nó khó cho bạn.
PHP:
Sub WB()
Dim WB As Workbook
    Set WB = Workbooks.Open("E:\EXCEL\VBA\character.xlsm")
    With WB
        For
      
        Next
    End With
    WB.Close
    WB = Nothing
End Sub

Nên bật Local Window lên, nó rất là hay (tuyệt vời), nó báo các đối tượng đang hiện diện, giá trị, thuộc tính của nó. Kết hợp với phím F8 thì sẽ giúp em hiểu rõ đối tượng hơn, cách thức nhận giá trị của nó.

1660025090622.png

Tham khảo thêm giang hồ làm nè: http://www.vbaexpress.com/kb/getarticle.php?kb_id=549

PHP:
Option Explicit
 
Sub AddBullet()
    
    Dim Bullet          As String
    Dim Dash            As String
    Dim Cel             As Range
    Dim Str             As String
    Dim i               As Long
    
    Bullet = "? "
    Dash = "   - "
     'select which cells to perform an action on
    For Each Cel In Selection
        Str = Cel.Value
         'If there is already a bullet there then put a dash in its place
        If Left(Str, Len(Bullet)) = Bullet Then
            Str = Right(Str, Len(Str) - 2)
            Cel.Value = Dash & Str
        Else
             'If there is already a dash there then trim back to normal text
            If Left(Str, Len(Dash)) = Dash Then
                Str = Trim(Cel.Value)
                i = Len(Str) - 1
                If i >= 0 Then
                    Cel.Value = Trim(Right(Str, i))
                End If
            Else
                 'Otherwise add the bullet
                Cel.Value = Bullet & Str
            End If
        End If
         'Go to the next cell in the selection and do the same thing
    Next Cel
    
End Sub
 
Upvote 0
Theo mình bạn nên xác định cái đối tượng ban đầu định mang nó ra xử là gì ?
Xong mang nó ra để xử, hết thì đóng lại, thay vì "E:\EXCEL\VBA\character.xlsm" ; bên dưới Workbooks("character.xlsm").Close thì nó khó cho bạn.
Hình như đoạn này đi hơi xa so với câu hỏi của em nó rồi :D .
Nhưng nếu nói về sự thuận tiện, thì viết cái addin rồi xử lý file nào thì mở file đó lên chạy addin có phải hơn không?
 
Upvote 0
Web KT
Back
Top Bottom