

---Xem file đính kèm nhé, nhớ Enable Macro.
)


Trường hợp công thức làm đựoc không bạn?Xem file đính kèm nhé, nhớ Enable Macro.
Trường hợp công thức làm đựoc không bạn?
[B]Function Join(Rng As Range) As String
Dim cll As Range, Tmp As String
For Each cll In Rng
Tmp = Tmp & cll & " "
Next cll
Join = Left(Tmp, Len(Tmp) - 1)
End Function
[/B]




Function Join(Rng As Range) As String
Dim cll As Range
For Each cll In Rng
Join = Join & cll & " "
Next cll
Join = RTrim(Join)
End Function

Được bạn ạ. Nếu bạn không dành về VBA bạn có thể dùng công thức củ chuối sau.Trường hợp công thức làm đựoc không bạn?

Tôi thấy cách dùng biến tạm để tính toán và trả về kết quả cho hàm hay hơn là tính toán trực tiếp vào tên hàm(Ý kiến cá nhân của tôi), còn dùng hàm RTrim để loại bỏ dấu cách thừa ở cuối như bạn trong trường hợp này có vẻ không đúng lắm, vì nó cắt tất cả các dấu cách ở cuối, trong khi đó trong quá trình tính toán ta chỉ thừa có 1 dấu cách ở cuối mà thôi, nếu ô cuối cùng có dấu cách ở cuối thì sao???Hàm của ptlong04x1 có thể bớt đi 1 biến và 2 phép tính:
Mã:Function Join(Rng As Range) As String Dim cll As Range For Each cll In Rng Join = Join & cll & " " Next cll Join = RTrim(Join) End Function
Xử lý dấu cách theo tôi cũng không cần thiết ---> Của người ta sao cứ để vậy, biết đâu người ta thích thế!còn dùng hàm RTrim để loại bỏ dấu cách thừa ở cuối như bạn trong trường hợp này có vẻ không đúng lắm, vì nó cắt tất cả các dấu cách ở cuối, trong khi đó trong quá trình tính toán ta chỉ thừa có 1 dấu cách ở cuối mà thôi, nếu ô cuối cùng có dấu cách ở cuối thì sao???


---
Trong trường hợp vùng không liên tục thì viết chắc khó hơn phải không bạn ptlong04x1?
( Hỏi thêm thôi)
Có 1 cách khác mà tôi cho là tuyệt chiêu, đó là nối các từ với nhau bằng dấu phân cách ---> Ra được kết quả ta dùng TRIM để loại các dấu cách thừa (khỏi IF)Anh thêm cái : If Cll <> "" Then ... là được mà.
Function JoinText(Range As Range, Sep As String) As String
Dim Clls As Range, Tmp As String
For Each Clls In Range
Tmp = Tmp & " " & Clls.Value
Next Clls
JoinText = Replace(WorksheetFunction.Trim(Tmp), " ", Sep)
End Function

Option Explicit
Public Function ConcSep_Array(InArray() As Variant, Optional Sep As String) As String
On Error Resume Next
Dim OutStr As String
Dim i, j As Integer
For i = LBound(InArray, 1) To UBound(InArray, 1)
For j = LBound(InArray, 2) To UBound(InArray, 2)
If InArray(i, j) <> "" Then OutStr = OutStr & InArray(i, j) & Sep
Next j
Next i
ConcSep_Array = Left(OutStr, Len(OutStr) - Len(Sep))
End Function
Public Function ConcSep_Range(InCells As Range, Optional Sep As String) As String
On Error Resume Next
Dim OutStr As String, Cell As Range
For Each Cell In InCells
If Cell <> "" Then OutStr = OutStr & Cell & Sep
Next
ConSep = Left(OutStr, Len(OutStr) - Len(Sep))
End Function
Bạn mô tả thế nghe giống nối chuổi có điều kiện ---> Mời bạn tham khảo bài này:Chào các bạn,
Xem ra mình đến với chủ đề này hơi trễ. Mình cũng đã từng gặp phải vấn đề này trong quá khứ và cũng giải quyết bằng một UDF giống như UDF ở trên. Ưu điểm thì như các bạn đã nêu là có thể nối các ô không liền nhau và người sử dụng có thể tùy chọn nhóm ký tự ngăn cách.
Trong trường hợp những cái bạn muốn nối không chỉ đơn thuần là các ô, mà là các thành phần của mảng (array) thì sao? Mình xin giới thiệu một UDF khác khá tương tự có thể giải quyết vấn đề này.
Các bạn có thể thắc mắc tại sao tui lại muốn nối thành phần mảng với nhau, chỉ cần nối các cell trong một range tự chọn là được rồi? Mình xin phép được trả lời nó sẽ hữu dụng trong trường hợp bạn muốn nối một số cell trong một range được chọn (chứ không phải nối hết), và một số này là bao nhiêu thì tùy vào điều kiện được đặt ở một cột/hàng tương ứng khác.
Ví dụ:
Cột A: loại máy ("new" hoặc "second-hand")
Cột B: tên máy
Bạn cần một công thức có thể nối tên các máy mới lại với nhau, được ngăn cách bởi dấu phẩy. Đương nhiên bạn sẽ không coi nguyên cột B rồi đánh dấu lại cell nào là cell máy mới rồi. Giải quyết như sau:
1) Trước hết, đặt tên (name range) cho các cột của bảng: loai_may và ten_may.
2) Viết công thức mảng tạo một mảng (chứ không phải range) bao gồm các cell máy mới:
If(loai_may="new";"ten_may";"") bạn lưu ý công thức mảng này chưa sử dụng được-->xem bước 3
3) Chuyển mảng này qua cho UDF xử lý. UDF của mình được gọi là ConcSep_Array (viết tắt của Concatenate with separators for arrays).
ConcSep_Array(If(loai_may="new";"ten_may";"");", ") rồi nhấn Ctrl-Shift-Enter
Dưới đây là 2 UDF mình đã giới thiệu ở trên, một dùng cho array, một dùng cho range:
Mã:Option Explicit Public Function ConcSep_Array(InArray() As Variant, Optional Sep As String) As String On Error Resume Next Dim OutStr As String Dim i, j As Integer For i = LBound(InArray, 1) To UBound(InArray, 1) For j = LBound(InArray, 2) To UBound(InArray, 2) If InArray(i, j) <> "" Then OutStr = OutStr & InArray(i, j) & Sep Next j Next i ConcSep_Array = Left(OutStr, Len(OutStr) - Len(Sep)) End Function Public Function ConcSep_Range(InCells As Range, Optional Sep As String) As String On Error Resume Next Dim OutStr As String, Cell As Range For Each Cell In InCells If Cell <> "" Then OutStr = OutStr & Cell & Sep Next ConSep = Left(OutStr, Len(OutStr) - Len(Sep)) End Function




Bạn thử xem file bên dưới xem. Nó có hạn chế là số dòng mình chỉ để 51 dòng thôi! nhiều hơn nữa mình nghĩ bạn nền dùng VBA!




Hic mở nhiều tab nên reply nhầmTopic này người ta hỏi từ năm 2009 đấy bạn! Giờ bạn mới trả lời?