Excel VBA Course
Excel VBA Course - From Beginner to Expert

200+ Video Lessons
50+ Hours of Video
200+ Excel Guides

Become a master of VBA and Macros in Excel and learn how to automate all of your tasks in Excel with this online course. (No VBA experience required.)

View Course

Extracting data from a cell into a formatted table.

0

Hello,

I want to extract data in cells of a column into structured and formatted rows. In the Excel file I attached is an example of the cells format that contains data export from my company's internal system. However, in column A, multiple fields are combined into a single cell making the cell contains several data from several column. (in the original data export file, the column that contains multiple data from different columns can be in position between column A and the last column, depending on the selected checkboxes in the filter menu before exporting the file)

I need to find a way to extract the data from this cell to assist with my work. Could you please help me to solve this problem?

Looking forward to your reply, thank you.

Answer
Discuss

Discussion

Hi Fida

Does your system deliver the contents of cells A2:A5 in exactly that way or could filter settings deliver it into columns? I assume you want an (array) formula (or perhaps VBA) to extract to what your sample file shows in B2:H5 but could the order of columns be different and can the number of connectors exceed 3 (per row)?

Which version of Excel are you using? (You should add that to your Forum Profile)
John_Ru (rep: 6142) Jul 3, '23 at 8:26 am
Hi John,

Yes, the data export from the EV charging network database in my company present that kind of data. So in cells A2:A5 is just a little example of the raw data export. Usually when I export the data there will be around 700 rows and 10 to 20 columns. So what I am trying to say that for instance, I want to export some particular data and apply particular filter that should be resulted in 10 columns, but the system somehow only give me 7 columns because it merges the data in the 3 columns into one single column only which gives the result like in the example in content A2:A5. Because the system merge the data like that, I can't count the total connectors number, I can only see the dashboard they present in their portal.

Also, I am using Excel 365 here in my work laptop and yes I'd like to know a function or vba code that can extract data from the single column that had combined data from multiple columns, and automatically calculate the number of connectors based on the available status in that column. The status can be "available", "charging","unknown" & "suspended, 90% the charging station status are available. The maximum number of connectors is 3, and the minimum is 1. So, in cells A2:A5, it represents the number of connectors present in a single charging station. Please let me know if you need more information and about the posibility of my request. 🙂
Fida_mutia (rep: 28) Jul 3, '23 at 10:53 am
Fida

Thanks confirming that you use Excel 365- please edit your profile to say that (rather than the current MS Office Version: Fida_mutia !) - it can decide what is an appropriate answer sometimes. 

I see no option but VBA to do what you're trying to do.

Do all connector names start the same "DC..."? 

The problem appears to be that the cell lists 1 to 3 connector names then 1 to 3 availability statuses (and in one case more than the number connectors) plus variable spaces and unwanted text. 

I've got a partial solution done (which would handle 700 or more rows) but I think you should first see if system filtering can produce separate columns or (if they're still combined in one column) include text with connector/ availability in pairs. 
John_Ru (rep: 6142) Jul 3, '23 at 3:41 pm
Hi John,

The connector names aren't start with "DC", That's just a pseudonym I used for privacy reasons. However, the name can still be used for example because the number and structure of the ID are the same as the original name. Also, do you need an actual example of data export from the database? i'll change some contents of the data from the original one

As for the internal database system in my company, it's called Greenflux software, and the software doesn't provide the column structure I desire since I started working here. It should be possible, but there haven't been any discussions in that direction yet.
Fida_mutia (rep: 28) Jul 3, '23 at 9:36 pm
Fida. Thanks for replying promptly; an actual output from your database would be useful (you can add it as a second file).

I asked about charger name format since we need to differentiate between those and status values (given you seem to be getting text which can be filtered to... name name status status status... ). Did your comnent above list every possible status? 

In the event that the number of names differs from statuses, which should be used to calculate the number of connectors? 

I'll try to look at your response later but have little time today and tomorrow. 
John_Ru (rep: 6142) Jul 4, '23 at 1:26 am
Fida

You didn't reply to my questions above.

I have a working solution but I'm reluctant to share it with you until you reply, not least because I suspect you won't understand it. If it's suitable, it would do in seconds what a human would take hours (if there are hundreds of cells with combined texts in a column).

Kindly respond.
John_Ru (rep: 6142) Jul 5, '23 at 8:54 am
Hi John!

My apologies for late reply but I've been swamped with work as usual. Also I need time to compile the real output from the database because I need to change some value due to data privacy but also make sure it's not deviating from the big picture of the data. Please wait a moment I'll get back with the data export that I'll edit first.
Fida_mutia (rep: 28) Jul 5, '23 at 9:08 am
Hi John, I have added the file which is the data export from Greenflux (GFX), the database in my company. However, I have removed some data values due to privacy. I also have added comments at the bottom row of the data range around columns A and B to provide more detailed information about my request. 
Fida_mutia (rep: 28) Jul 5, '23 at 9:33 am
Fida

Thanks for attaching the file with GFX output. I was surprised to see that you're based in the UK (like me).

Extracting column I of that file (the combined connector text)  "in situ" is possible, in fact a small extension of what I have done already. This is a Q&A forum but you've definitely strayed into specifying a mini-project, and one I suspect would save a lot of time. I can do it but why isn't your company getting someone to do it for you? (From your previous questions I suspect your knowledge of Excel is moderate).
John_Ru (rep: 6142) Jul 5, '23 at 4:06 pm
Well, actually, I'm not based in the UK. 😁 I live in Asia. It's just that I work remotely from here and the company I work for is based in the UK. Great to hear that you're based in UK btw! 😀 As for why my company can't assign someone to do it for me because everyone here has already swamped with work like myself and also maybe the analysts here aren't capable to do it. I'm not sure if the analysts here can even code in VBA and I'm just working as Administration staff here so yeah my Excel skill is not on expert lvl.
Fida_mutia (rep: 28) Jul 5, '23 at 9:43 pm
Understood Fida. Looking at the GFX file, will the connector data always be in column I?
John_Ru (rep: 6142) Jul 6, '23 at 7:45 am
No, because it depends on the filter applied before downloading the data. So maybe it's better if I just copy only the connector column to another sheet and then be able to extract the merged data in that column.
Fida_mutia (rep: 28) Jul 6, '23 at 8:44 am
It's okay, I can add an input box for you to say which column it is (then extract it to new columns to the right of it (so you can check it looks correct)
John_Ru (rep: 6142) Jul 6, '23 at 10:00 am
Thats great! I can work with that 😀
Fida_mutia (rep: 28) Jul 7, '23 at 4:43 am
Good (though it was more work for me).

Found some shortcomings in the information in your question (now fixed) but want to add one improvement before posting answer (in an hour or so- once you correct your Excel version in your profile please!).

How long would it take to edit that sample GFX?
John_Ru (rep: 6142) Jul 7, '23 at 5:46 am
Thanks a lot John for the VBA code, but I can't run the macro. I previously downloaded the Excel file you given on my work laptop and received a security risk warning. Then I tried downloading the file on my personal laptop, but the macros still won't run bcs I still have this "security risk" warning. I adjusted the Macro Settings in Trust Center, but the issue persists. I'm unsure about the next steps to resolve this issue. Can you please advise me on what steps I should take?
Fida_mutia (rep: 28) Jul 8, '23 at 1:52 am
Fida. I really want you to see the file running since I was quite pleased to solve an intriguing problem (one which I couldn't see how to fix without VBA code).

You can read Microsoft's guidance note here: Macros from the internet will be blocked by default in Officet It tells you how unblock the macros in this section (but I can't post the picture);

Guidance on allowing VBA macros to run in files you trust

Remove Mark of the Web from a file
For an individual file, such as a file downloaded from an internet location or an email attachment the user has saved to their local device, the simplest way to unblock macros is to remove Mark of the Web. To remove, right-click on the file, choose Properties, and then select the Unblock checkbox on the General tab


Please try and let me have your comment but note that if you have any problems I won't be able to fix them today or tomorrow. Kindly add any comments on the Answer under its Discussion thread, not here.
John_Ru (rep: 6142) Jul 8, '23 at 3:14 am
Fida.

Please see revised Answer and use the revised file instead- I noticed that rows 580, 584 and 588 had no total (since EV and suspended weren't present in my code). It should now correctly extract the details of over 1,100 connectors in less than a second!
John_Ru (rep: 6142) Jul 8, '23 at 4:15 am
Hi Fida. Did you try that revised file? 
John_Ru (rep: 6142) Jul 10, '23 at 2:46 am
Hi John, sorry I can't give you update for today. I'm currently overwhelmed as usual on Monday. I'll try to send my reply tomorrow evening or Tuesday at the latest. I also still need more time to understand your instruction here. Nevertheless, thanks a lot for your support!
Fida_mutia (rep: 28) Jul 10, '23 at 7:08 am
No problem Fida. I think the code will save you or someone a lot of time so perhaps make your life a little easier!
John_Ru (rep: 6142) Jul 10, '23 at 9:41 am
Fida, please don't forget to respond to my Answer. It took me quite a bit of work but I'm pleased that I solved your problem. Hope you agree. 
John_Ru (rep: 6142) Jul 15, '23 at 11:07 am
Okay Fida- I give up! I think my Answer would save you hours of work but it can't if you haven't tried it. Bye until next time!
John_Ru (rep: 6142) Jul 18, '23 at 10:07 am
Fida. I'm surprised you didn't respond to my Answer. Please do so, if you get chance. 
John_Ru (rep: 6142) Jul 31, '23 at 2:06 pm
Hi John, my apologies for the very late response. I will take a look at the article you sent here on how to unblock the security check. This area is very complicated from my side as well as to understand your code and the workflow. I'll need to discuss with my team who got specialty about vba macro. I'll try to get back to you soon as I have an update 😀
Fida_mutia (rep: 28) Feb 29, '24 at 10:41 am
Thanks Fida, I'd quite forgotten about that. I remember being pleased to have created a good solution (in my opinion) and disappointed to get no response. 
John_Ru (rep: 6142) Feb 29, '24 at 11:26 am
Add to Discussion

Answers

0
Selected Answer

Fida

I can't think of a non-VBA method to acheive what you want.

Normally the Forum is limited to Q&A and users shouldn't specify what becomes a mini-project (but you got lucky this once!).

In the attached revised, file I've added the code below (with extensive comments) in Module 2. It needs to be run with macros-enabled (look on the internet to see how).

 If you select the worksheet GFX, that contains the sample you provived (with combined data in column I). Press key combination Ctrl + Shift + J and the code below will run, asking you questions, extracting the connector detail and telling you of problems (see below):

Sub ExtractConnectors()
'
' Custom code to extract connector details and ignore other texts
' Created by John_Ru (TeachExcel)
' Supplied as seen, the author accepts no liabilities for errors or data loss caused through use
' Keyboard Shortcut: Ctrl+Shift+J
'

    Dim NumCol
    Dim Inpt As String, Outpt As String, DeLim As String
    Dim Rw As Long, LstRw As Long, n As Long, p As Long
    Dim Chrctr As String, TempArray As Variant
    Dim OutArray As Variant ' array for <= 3 * connectors/statuses and total
    Dim IgnoreArray As Variant ' for array of unwanted text entries
    Dim StatusArray As Variant ' for array of all status entries
    Dim ConnPos As Long, StatusPos As Long, Overs As String

    ' set delimiter character
    DeLim = "|"
    ' set entries to ignore
    IgnoreArray = Array("", "1", "+1", "2", "3", "EV", "EVSEs", "connector", "connector1", "connector2", "connector3")
    ' set strings used as status (added missing items found)
    StatusArray = Array("available", "charging", "unknown", "suspended", "suspended EV", "finishing", "faulted", "preparing", "unavailable")
    
    ' ask user where combined text data is
    NumCol = InputBox("Type the letter of the column where connector data is combined (e.g. A)" _
            & vbCr & vbCr & "(7 columns will be inserted to its right)", _
            "Extract connectors from combined text", "I")
    If NumCol = "" Then Exit Sub
    ' handle numbers entered
    If IsNumeric(NumCol) Then
        r = MsgBox("Column " & NumCol & "?" & _
            " Do you mean column " & Split(Cells(1, CInt(NumCol)).Address, "$")(1) & "?", _
            vbYesNo)
            If r = vbNo Then Exit Sub
            ' save as column number
            NumCol = CInt(NumCol)
            Else
            ' convert to column number
            NumCol = Range(NumCol & "1").Column
    End If

    ' determine last used row in A (column 1)
    LstRw = Cells(Rows.Count, NumCol).End(xlUp).Row
    ' add 7 new (yellow) columns to right for results
    Cells(1, NumCol + 1).Resize(1, 7).EntireColumn.Insert
    With Cells(1, NumCol + 1).Resize(1, 7).EntireColumn
        .Interior.Color = vbYellow
        .WrapText = False
    End With

    ' loop down rows
    For Rw = 2 To LstRw
        Inpt = Cells(Rw, NumCol).Text
        Outpt = ""
        Prt = ""
        Frst = False
        ' loop through cells
        For n = 1 To Len(Inpt)
            ' look at nth character in strin
            Chrctr = Mid(Inpt, n, 1)
            ' if it's a space...
            If Asc(Chrctr) = 32 Then
                If Frst = True Then
                    ' ... and first since text end, add delimiter to output string
                    Frst = False
                    Outpt = Outpt + DeLim

                    Else
                    ' otherwise ignore it
                    Frst = False
                End If

            Else
            ' if not a space, reset the First(space) flag
            Frst = True
            ' and add character to output string
            Outpt = Outpt & Chrctr

            End If
        Next n

        ' split remainder into an array
        TempArray = Split(Outpt, DeLim)

        ' compare that to Ignore and Status arrays
        ' first, reset output position pointers
        ConnPos = 1
        StatusPos = 2
        ' clear output array (don't preserve contents)
        ReDim OutArray(1 To 7)

        ' loop through array
        For p = LBound(TempArray, 1) To UBound(TempArray, 1)
            'check ignore words
            For n = LBound(IgnoreArray, 1) To UBound(IgnoreArray, 1)
                ' if a (case-insensitive) Ignore term, set entry to ""
                If LCase(TempArray(p)) = LCase(IgnoreArray(n)) Then
                    TempArray(p) = ""
                    Exit For
                End If
            Next n

            'if not...
            If TempArray(p) <> "" Then
               ' ..., check is it's a status
               For n = LBound(StatusArray, 1) To UBound(StatusArray, 1)
                    ' if a (case-insensitive) Status, write to output and set entry to ""
                    If LCase(TempArray(p)) = LCase(StatusArray(n)) Then
                        ' write status then increment pointer (or record error)
                        OutArray(StatusPos) = TempArray(p)
                        If StatusPos <= 6 Then
                            StatusPos = StatusPos + 2
                            Else
                            Overs = Overs & Rw & ", "
                            Exit For
                        End If
                        ' increment total
                        OutArray(7) = OutArray(7) + 1
                        TempArray(p) = ""
                        Exit For
                    End If
                Next n
            End If

            'if not ignored or status, assume it's a connector
            If TempArray(p) <> "" Then
                ' write connector name then increment pointer (or record/highlight error)
                OutArray(ConnPos) = TempArray(p)
                If ConnPos <= 5 Then
                    ConnPos = ConnPos + 2
                    Else
                    ' record row
                    Overs = Overs & Rw & ", "
                    ' set cell and extract to red then select
                    With Range(Cells(Rw, NumCol), Cells(Rw, NumCol + 7))
                        .Interior.Color = vbRed
                        .Select
                    End With
                    Exit For
                End If
            End If

        Next p
        ' write connectors + status  to row, total at end
        Range(Cells(Rw, NumCol + 1), Cells(Rw, NumCol + 7)) = OutArray
    Next Rw

    ' write headers and autofit results
        With Range(Cells(1, NumCol + 1), Cells(1, NumCol + 7))
            .Value = Array("EVSE 1", "Connector 1 Status", _
                        "EVSE 2", "Connector 2 Status", _
                        "EVSE 3", "Connector 3 Status", _
                        "Total Connectors")
            .EntireColumn.AutoFit
        End With
' tell user
MsgBox "Connectors extracted to right of column " & Split(Cells(1, CInt(NumCol)).Address, "$")(1) & " (filled yellow)"
' warn user if errors found
If Overs <> "" Then r = MsgBox("Problem- more than 3 connectors in these rows: " & Overs & "(in red, last row cell/extract selected)", vbExclamation, "Manual extraction of data needed!")

End Sub

If you state the correct column letter (I in the attached file, but could be another within other extracts and it will check if you enter a number instead), it will add 7 yellow columns to the right and extract data. The Total Connectors figure in the rightmost is a correct count of Status entries, not connector names (unless there's more than the maximum 3 you said...)

Currently it will show errors for rows 509 and 510- where there are more than 3 status entries in the combined text. Not sure what you do if there are more than 3 but over to you!

The discussion on your question missed some information but I corrected that in the lines beow (missing items in bold):

  ' set entries to ignore
    IgnoreArray = Array("", "1", "+1", "2", "3", "EV","EVSEs", "connector", "connector1", "connector2", "connector3")
    ' set strings used as status (added missing items found)
    StatusArray = Array("available", "charging", "unknown", "suspended", "suspended EV", "finishing", "faulted", "preparing", "unavailable")

Revision 08 July 2023 (added "EV" to IgnoreArray, "suspended to StatusArray to above and full code; attached a revised file ...v0_b.xlsm)

These lines are critical to "filtering"/ text extraction done by the code (and you may need to adjust them in future) or it might identify other texts as connector names.

I suspect it does in a second or so what would take an hour or more manually. All you have to do is check it worked well, correct any errors, adjust the formatting and delete the source column (if necessary).

Hope this works well for you (it took some effort from me!).If so, please mark this Answer as Selected

Discuss

Discussion

Hi Fida. Please let me have feedback on the Answer above.
John_Ru (rep: 6142) Jul 17, '23 at 3:29 pm
Did that work for you, Fida? 
John_Ru (rep: 6142) Jul 25, '23 at 1:08 am
Hi John, I got notifictaion "Complie error:" then below it is "Expected: case"

I put the column that I want to extract on column A, is there something wrong with it?
Fida_mutia (rep: 28) Mar 1, '24 at 12:39 am
Fida. 

Try entering number 1, not "A", since the code includes a test:

If IsNumeric(NumCol) Then
John_Ru (rep: 6142) Mar 1, '24 at 1:10 am
Oops! Forget that please -I answered just after waking.

I tried the file from my ANswer and it worked fine wioth "A" as the input. I've never seen that  "Expected: case" message as far as I recall. Please download the Answer file again, try and let me know.
John_Ru (rep: 6142) Mar 1, '24 at 7:11 am
Add to Discussion


Answer the Question

You must create an account to use the forum. Create an Account or Login