0

I'm learning VBA and trying to do something a bit complicated for me. Here's the deal :

My Excel file

In my "H" column, I'm using the "CONCATENATE" formula to get a key of all the elements I want in my columns, for each line. As you can see, some elements aren't filled and I'm having unwanted " - " separators. I'd like to have a macro that searches and replaces the double, triple (...) separators that I don't want, and if there a line filled only with separators (i.e my H5 cell) I'd like it to be replaced with nothing instead.

The thing is, I'd like to add some columns/lines in the future and I don't want to change the macro every time I'm adding a column or a line. Consequently, it'd be great if there was a way to say to my macro: "Whenever there's a line filled with nothing but separators, replace it with nothing".

This is the part I don't know how to deal with. Could you guys give me a hint?

Thanks and sorry for the long post, here's a kawaii potato

potato - Hi 9gag users!

Jeanjean
  • 723
  • 2
  • 12
  • 22
  • What version of Excel are you using? In 2016, there's =TextJoin()` which I think is what you're wanting. `=TEXTJOIN(" - ",TRUE,A2:G2)` – BruceWayne Dec 15 '16 at 22:05
  • [This may give you a nice approach](http://stackoverflow.com/questions/27833805/joining-a-range-of-cells-in-excel-using), just add the condition if <>"" in the if statement – Sgdva Dec 15 '16 at 22:11

2 Answers2

4

TEXTJOIN(delimiter, ignore_empty, text1, [text2], …)

=TEXTJOIN(" - ",TRUE,A2:G2)

enter image description here

UPDATE: If your version of Excel doesn't have TEXTJOIN

Function UDFTextTJoin(delimiter As String, ignore_empty As Boolean, ParamArray Text()) As String
    Dim s As String
    Dim v As Variant
    Dim x As Long

    For x = 0 To UBound(Text)
        If TypeName(Text(x)) = "Range" Then
            For Each v In Text(x)
                If Not ignore_empty Or v <> "" Then
                    If Len(s) Then s = s & delimiter
                    s = s & v
                End If
            Next
        Else

            If Not ignore_empty Or Text(x) <> "" Then
                If Len(s) Then s = s & delimiter
                s = s & Text(x)
            End If
        End If
    Next

    UDFTextTJoin = s

End Function
  • This was one of my favorite formulas they put in the newer version of Excel. I'm surprised they didn't think to do it sooner. – BruceWayne Dec 15 '16 at 22:17
  • This is awesome, my office version at work is not the 2016 edition :( – Jeanjean Dec 15 '16 at 22:24
  • @Jean-FIC - If you could - this is a great example of why to upgrade! Now you have to introduce a macro, or write a relatively convoluted `If()` statement, to get what you want. Excel 2016 has some pretty solid upgrades that makes it worth the cost, IMO. Also, consider you're spending time (maybe even at work!) trying to solve this - when the new Excel has the solution already there :D – BruceWayne Dec 15 '16 at 22:34
  • 1
    @BruceWayne I forgot that `TEXTJOIN` was a new feature. I updated my answer to include my own version `UDFTextTJoin`. It was a little tricky to allow either ranges or text but I think that I got it. –  Dec 15 '16 at 22:36
  • Thanks Thomas, you rock! I'll try this as well tmrow. Time to sleep! Thanks for your time. Much appreciated! – Jeanjean Dec 15 '16 at 22:36
  • @ThomasInzina IIRC I asked a similar question to OP here and someone showed me TextJoin. It's so much better than macros or the crazy `If()` statement I had written. Nicely done! – BruceWayne Dec 15 '16 at 22:37
  • hey!, I did it too :D. Wonder why mine is a bit shorter, probably because approximated, but it seems to work for me. – A.S.H Dec 15 '16 at 22:38
  • @A.S.H I took it to an extreme to allow mixing text and ranges - `=UDFTextTJoin(" - ",TRUE,A1:C1,"CAT",D1:F1,"DOG")` –  Dec 15 '16 at 22:43
  • Yep, I see, mine does not take variable argument list. Nice job :) – A.S.H Dec 15 '16 at 22:44
  • 1
    @A.S.H Thanks. Your function will does meet the OP's needs - Kudos. –  Dec 15 '16 at 22:47
  • Hey guys thanks for your help. I got a computer with the 2016 version of Excel yay! Unfortunately I have another problem haha... I thought I had a great idea but it is not working! New post over here for those who like challenges : http://stackoverflow.com/questions/41193302/concatenate-and-textjoin-formulas-excel-vba Thanks again to everybody !!! – Jeanjean Dec 16 '16 at 22:26
1

For sure there are methods to avoid the pattern from the very beginning, but this is a Macro to do a (late) cleanup:

Sub Cleanup()
    Dim cel As Range, i As Long
    With Worksheets("Products").UsedRange.Columns("J")
        For i = 1 To 5
           .Replace "- - ", "- "
        Next
        For Each cel In .Cells
            If Trim(cel.Value) = "-" Then cel.Clear
        Next
    End With
End Sub

EDIT:

Since you and I dont have TextJoin, and it is an excellent solution proposed by the pals, let us have it as UDF. You can add the code below to any non-class code module and use it as User-Defined-Formula (UDF):

Public Function TextJoin(ByVal sep As String, ByVal ignoreEmpty As Boolean, ByRef ar As Variant) As String

    Dim cel As Range
    For Each cel In ar
        If Trim(cel.Text) <> "" Or Not ignoreEmpty Then
            If TextJoin <> "" Then TextJoin = TextJoin + sep
            TextJoin = TextJoin + cel.Text
        End If
    Next
End Function
A.S.H
  • 29,101
  • 5
  • 23
  • 50
  • As an alternative, could this be turned into a UDF, in the event they don't have `TextJoin()`? They could just run `=cleanUp([range])`. – BruceWayne Dec 15 '16 at 22:16
  • @BruceWayne for sure, `TextJoin` could be written in VBA if not available. If the OP wishes, we can write it and avoid the pattern from the beginning. Otherwise this could be a simple handy macro if they dont want to change their formulas. BTW, at this host I dont have `TextJoin` either. – A.S.H Dec 15 '16 at 22:18
  • Thanks A.S.H ! I'll try this later on and will come back to you. Have a great night! – Jeanjean Dec 15 '16 at 22:24