Làm sao để xuống dòng mỗi khi thỏa mãn điều kiện?

  • Thread starter Thread starter Trojan
  • Ngày gửi Ngày gửi
Liên hệ QC

Trojan

Thành viên hoạt động
Tham gia
13/3/08
Bài viết
162
Được thích
78
Trong mỗi một cell của tôi có nội dung là "người gửi: Nguyễn Văn A địa chỉ: Hà Nội"... Trong VBA tôi có nhu cầu là tìm trong mỗi cell đó cứ mỗi khi gặp text là "địa chỉ" thì tự động sẽ xuống dòng nhưng vẫn trong cell đó (như kiểu dùng alt+enter). Mọi người trong diễn đàn tư vấn giúp tôi cái yêu cầu này với. Xin cảm ơn nhiều.
 
Trong mỗi một cell của tôi có nội dung là "người gửi: Nguyễn Văn A địa chỉ: Hà Nội"... Trong VBA tôi có nhu cầu là tìm trong mỗi cell đó cứ mỗi khi gặp text là "địa chỉ" thì tự động sẽ xuống dòng nhưng vẫn trong cell đó (như kiểu dùng alt+enter). Mọi người trong diễn đàn tư vấn giúp tôi cái yêu cầu này với. Xin cảm ơn nhiều.
Chỉ là gợi ý bạn thực hiện thử xem sao : Bạn dùng sự kiện Worksheet_Change. Trong đó, mỗi khi nhập liệu thì nó sẽ kiểm tra nội dung. Nếu thấy nội dung có chứa từ "địa chỉ" thì nó thêm ký tự xuống dòng trước từ "địa chỉ" ( &Chr(13) ). Cuối cùng, gán nội dung mới trở lại cho Cell

TDN
 
Upvote 0
Chỉ là gợi ý bạn thực hiện thử xem sao : Bạn dùng sự kiện Worksheet_Change. Trong đó, mỗi khi nhập liệu thì nó sẽ kiểm tra nội dung. Nếu thấy nội dung có chứa từ "địa chỉ" thì nó thêm ký tự xuống dòng trước từ "địa chỉ" ( &Chr(13) ). Cuối cùng, gán nội dung mới trở lại cho Cell

TDN
Xin phép góp 1 code
PHP:
Sub XuongDong()
Dim eRow As Long, iText As String, jText As String
jText = [f1] 'diachi cai nayphai gan cho 1 cell nao do thi no moi hieu unicode
eRow = [A65000].End(xlUp).Row 'dong cuoi
For i = 1 To eRow
    iText = WorksheetFunction.Clean(Range("A" & i)) 'Remove Chr(13)
    iText = Replace(iText, jText, Chr(10) & jText, 1) 'them Chr(13)
    Range("A" & i) = iText 'gan lai
Next
   With Range("A1:A" & eRow) 'dinh dang co wraptext
        .HorizontalAlignment = xlGeneral
        .VerticalAlignment = xlBottom
        .WrapText = True
    End With
End Sub
 

File đính kèm

Upvote 0
Thêm 1 cách nữa tự động luôn:
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
  Application.EnableEvents = False
  On Error Resume Next
  If Not Intersect([A1:A100], Target) Is Nothing Then
    Target = Replace(Target, " " & Evaluate("DC"), Chr(10) & Evaluate("DC"), 1)
  End If
  Application.EnableEvents = True
End Sub
Với DC là name có nội dung = "Địa chỉ"
Và đương nhiên chỉ sau khi gõ xong, Enter thì code mới thực hiện
 

File đính kèm

Upvote 0
Xin giới thiệu thêm 1 cách nữa như sau, viết thêm 1 hàm và sử dụng hàm để xử lý, cho phép dùng hàm với mọi ô và có thể chỉ định chuỗi điều kiện động:
Mã:
[B]
Function BreakDown(strSource As String, strSeparator As String) As String
    BreakDown = Replace(strSource, strSeparator, vbNewLine & strSeparator)
End Function
[/B]

Cách sử dụng hàm như sau: Giả sử ô A1 của bạn chứa dữ liệu cần xử lý:
Người gửi: Lê Hòa Địa chỉ: Hà Nội
Tại ô A2 bạn nhập vào công thức:
=BreakDown(A1,"Địa chỉ")
(Ô A2 phải được định dạng Wrap Text=True)
Download
 

File đính kèm

Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Đề tài của bạn TroJan rất hữu ích. Tiện đây tôi muốn mở rộng tý chút về một vấn đề " na ná" như của bạn:
Nếu một cell mà ta đánh đủ 255 ký tự rồi thì nó sẽ tự động xuống dòng tức là xuống rows kế tiếp cùng cột để đánh tiếp thì làm thế nào? Xin các bạn chỉ giáo luôn.
 
Upvote 0
Ý kiến của bạn Nguyễn Xuân Sơn mình xin có 1 hàm như sau để đáp ứng, có thể xuống dòng sau bao nhiêu ký tự là do người dùng nhập vào lúc sử dụng hàm
Mã:
Function BreakByLen(strSource As String, iLength As Long) As String
    If iLength <= 0 Then
        BreakByLen = strSource
        Exit Function
    End If
    Dim strRet As String
    strRet = ""
    Do While Len(strSource) > iLength
        strRet = strRet & Mid(strSource, 1, iLength) & vbNewLine
        strSource = Mid(strSource, iLength + 1)
    Loop
    BreakByLen = strRet & strSource
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
Không hiểu cách dùng hàm như thế nào?
Mình đoán vầy:
A1 = "Họ tên: Nguyễn Thị Mẹt Năm sinh: 1987"
B1 = breakdown(A1;"Năm")

Thực hành thì kết quả không thấy ngay, nhưng copy - Paste value thì thấy.
Hoặc format wraptext thì được.
 
Upvote 0
Mình đã có lưu ý là phải định dạng Wrap Text bằng True rồi mà. Chỉ có định dạng Wrap Text bằng True thì mới xuống dòng được. Khi bạn nhấn Alt+Enter trong lúc nhập liệu thì Excel tự động định dạng Wrap Text cho bạn rồi. Hàm chỉ làm thay cho bạn là Insert dấu Alt+Enter vào chỗ cần thiết thôi.
 
Upvote 0
Mình đã có lưu ý là phải định dạng Wrap Text bằng True rồi mà. Chỉ có định dạng Wrap Text bằng True thì mới xuống dòng được. Khi bạn nhấn Alt+Enter trong lúc nhập liệu thì Excel tự động định dạng Wrap Text cho bạn rồi. Hàm chỉ làm thay cho bạn là Insert dấu Alt+Enter vào chỗ cần thiết thôi.
Ôi dào... tưởng cái gì... Nếu là như thế thì cần gì viết hàm cho mệt! Hàm Excel đã có sẳn rồi đồng chí ơi (Nếu phải viết hàm thì tôi đâu cần dùng sự kiện WorkSheet_Change)
Đây này:
=SUBSTITUTE(A1," Địa chỉ",CHAR(10)&"Địa chỉ")
Cũng như đồng chí, sao khi gõ xong công thức thì tại cell này cũng cần Format Wrap text
Ẹc... Ẹc.... Xem file đính kèm đây!
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Đề tài của bạn TroJan rất hữu ích. Tiện đây tôi muốn mở rộng tý chút về một vấn đề " na ná" như của bạn:
Nếu một cell mà ta đánh đủ 255 ký tự rồi thì nó sẽ tự động xuống dòng tức là xuống rows kế tiếp cùng cột để đánh tiếp thì làm thế nào? Xin các bạn chỉ giáo luôn.
Có thể tôi viết không được rõ nghĩa nên bạn rollover79 có viết hàm "BreakByLen" như bài đã đăng. Vậy tôi xin nói thêm cho rõ ràng hơn: Khi tôi ở một cell bất kỳ ( một ô nào đó ), cứ đánh các ký tự " tràn cung mây" như trong word và theo mặc định nếu quá 255 ký tự nó sẽ tự động nhảy tiếp các ký tự xuống ô dưới và cứ như thế cho đến khi mình đánh xong đoạn văn thì thôi.
Vấn đề ở chỗ đó, xin nhờ bạn và các bạn chỉ giáo.
 
Upvote 0
Có thể tôi viết không được rõ nghĩa nên bạn rollover79 có viết hàm "BreakByLen" như bài đã đăng. Vậy tôi xin nói thêm cho rõ ràng hơn: Khi tôi ở một cell bất kỳ ( một ô nào đó ), cứ đánh các ký tự " tràn cung mây" như trong word và theo mặc định nếu quá 255 ký tự nó sẽ tự động nhảy tiếp các ký tự xuống ô dưới và cứ như thế cho đến khi mình đánh xong đoạn văn thì thôi.
Vấn đề ở chỗ đó, xin nhờ bạn và các bạn chỉ giáo.
Tôi hiểu ý bạn! Vậy nhiệm vụ của ta là tìm ký tự rổng nằm gần với vị trí 255 rồi thay nó thành Chr(10)...
Ai chà... cũng khó đây
 
Upvote 0
Có thể tôi viết không được rõ nghĩa nên bạn rollover79 có viết hàm "BreakByLen" như bài đã đăng. Vậy tôi xin nói thêm cho rõ ràng hơn: Khi tôi ở một cell bất kỳ ( một ô nào đó ), cứ đánh các ký tự " tràn cung mây" như trong word và theo mặc định nếu quá 255 ký tự nó sẽ tự động nhảy tiếp các ký tự xuống ô dưới và cứ như thế cho đến khi mình đánh xong đoạn văn thì thôi.
Vấn đề ở chỗ đó, xin nhờ bạn và các bạn chỉ giáo.

Điều này khó, vì khi đang nhập liệu thì ta đang ở chế độ Edit Cell, mà ở chế độ này thì VBA không hoạt động.
VBA chỉ hoạt động khi bạn thoát khỏi chế độ Edit Cell (Enter; Tab; -> . . . )
Nếu khi bạn nhập xong thì mới chạy code thì đơn giản hơn rất nhiều.

Thân!
 
Upvote 0
Cảm ơn bạn NDU, do mình hiểu sai ý của tác giả là phải tự động xuống dòng. Hàm SUBSTITUTE thì tôi cũng chưa dùng, chưa biết nên mới viết hàm riêng.
- Vấn đề của bạn Nguyễn Xuân Sơn tôi xin mạn phép kết hợp hàm BreakByLen của tôi với sự kiện WorkSheet_Change của bạn NDU đã viết để giải quyết như sau:
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
  Application.EnableEvents = False
  On Error Resume Next
  If Not Intersect([A1:A100], Target) Is Nothing Then
    ''''''Target = Replace(Target, " " & Evaluate("DC"), Chr(10) & Evaluate("DC"), 1)
    Target = BreakByLen(Target, 10)
  End If
  Application.EnableEvents = True
End Sub

Function BreakByLen(ByVal strSource As String, ByVal iLength As Long) As String
    If iLength <= 0 Then
        BreakByLen = strSource
        Exit Function
    End If
    Dim strRet As String
    strRet = ""
    Do While Len(strSource) > iLength
        strRet = strRet & Mid(strSource, 1, iLength) & vbNewLine
        strSource = Mid(strSource, iLength + 1)
    Loop
    BreakByLen = strRet & strSource
End Function
(Trong ví dụ trên và trong file đính kièm tôi xuống dòng sau 10 ký tự, cái này có thể thay đổi tùy ý)
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Thanks mọi người cùng thảo luận đề tài này. Trong các ví dụ trên chỉ có một điểm breakdown, nếu yêu cầu của tôi là 3 điểm breakdown thì làm thế nào? Xin hỏi mọi người. Cảm ơn nhiều.
 
Upvote 0
Mã của bạn rollover79 rất sáng tạo. Tuy nhiên cũng chỉ giải quyết xuống dòng trong cùng một ô ( vẫn như là Alt +Enter thôi). Ở đây tôi muốn đưa vấn đề ra bàn bạc là xuống 1 row ( ô dưới ) cơ. Nhưng có lẽ tôi đồng ý với ý kiến bạn "OKeBab" là vấn đề này không thể giải quyết được.
 
Upvote 0
Thanks mọi người cùng thảo luận đề tài này. Trong các ví dụ trên chỉ có một điểm breakdown, nếu yêu cầu của tôi là 3 điểm breakdown thì làm thế nào? Xin hỏi mọi người. Cảm ơn nhiều.
bạn xem file thử. Vùng breakdown là F1:F3
 

File đính kèm

Upvote 0
To Trojan: Mình nghĩ break bao nhiêu điểm cũng không quan trọng đâu, chỉnh sửa 1 chút là ok thôi.
To Nguyễn Xuân Sơn: Đã break trên cùng 1 ô được thì sẽ break xuống các ô phía dưới được thôi bạn ạ. Mình thử sửa lại 1 chút xem sao nhé. Nhưng khi break xuống những ô phía dưới nếu có dữ liệu sẽ bị đè đúng không?
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
  Application.EnableEvents = False
  On Error Resume Next
  Dim arrTemp, i
  Dim iColumn, iRow
  iColumn = Target.Column
  iRow = Target.Row
  If Not Intersect([A1:A100], Target) Is Nothing Then
    'Target = Replace(Target, " " & Evaluate("DC"), Chr(10) & Evaluate("DC"), 1)
    'Target = BreakByLen(Target, 10)
    arrTemp = Split(BreakByLen(Target, 10), Chr(10))
    For i = LBound(arrTemp) To UBound(arrTemp)
        Cells(iRow, iColumn) = arrTemp(i)
        iRow = iRow + 1
    Next
  End If
  Application.EnableEvents = True
End Sub

Function BreakByLen(ByVal strSource As String, ByVal iLength As Long) As String
    If iLength <= 0 Then
        BreakByLen = strSource
        Exit Function
    End If
    Dim strRet As String
    Dim iPos As Integer
    Dim strTemp As String
    strRet = ""
    strTemp = ""
    Do While Len(strSource) > iLength
        strTemp = Mid(strSource, 1, iLength)
        iPos = InStr(strTemp, Chr(10))
        If iPos = 0 Then iPos = InStrRev(strTemp, " ")
        If iPos > 0 Then strTemp = Mid(strTemp, 1, iPos - 1)
        If Mid(strSource, Len(strTemp) + 1, 1) = Chr(10) Then
            strSource = Mid(strSource, Len(strTemp) + 2)
        Else
            strSource = Mid(strSource, Len(strTemp) + 1)
        End If
        strRet = strRet & strTemp & Chr(10)
    Loop
    BreakByLen = strRet & strSource
End Function
(Trong hàm BreakByLen lần này tôi có sửa để nó break tại ký tự rỗng nằm gần cuối nhất theo ý của bạn NDU)
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
To Nguyễn Xuân Sơn: ..... Nhưng khi break xuống những ô phía dưới nếu có dữ liệu sẽ bị đè đúng không?
Mã:
Bái phục bạn ollover79. Đã đi thì đi tới " bến " luôn. Bởi vậy xin thỉnh giáo bạn chút xíu nữa: Liệu có khắc phục vấn đề " Khi break xuống những ô phía dưới nếu có dữ liệu sẽ bị đè " bằng cách trước khi break xuống ô phía dưới nó tự động insert dòng để đỡ bị đè dữ liệu ở ô dưới "nếu có" không?
 
Upvote 0
Mình sẽ sửa code để có thể tự động chèn thêm ô phía dưới nếu ô phía dưới có dữ liệu như sau(Chèn ô hay chèn dòng cũng giống nhau).Thêm 1 dòng lệnh sau dòng lệnh iRow = iRow + 1
Mã:
        iRow = iRow + 1
        If i <> UBound(arrTemp) And Cells(iRow, iColumn) <> "" Then Cells(iRow, iColumn).Insert
 
Upvote 0
Web KT

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

Back
Top Bottom