Forum Discussion
Concatenating column B values if left adjacent cell is empty
- Jul 16, 2019
I revised the macro to allow up to 200 more rows of results in case of overflow, as well as up to 165 characters in next pass through the concatenation loop. When an overflow situation is detected, the server name will be repeated as often as needed to get all software names listed on additional rows.
Sub Sequelize() Dim rg As Range Dim delimiter As String, s As String Dim i As Long, k As Long, n As Long, nData As Long Dim vData As Variant, vResults As Variant delimiter = ", " Set rg = Range("A2").CurrentRegion Set rg = rg.Offset(1, 0).Resize(rg.Rows.Count - 1, rg.Columns.Count) n = rg.Rows.Count nData = Application.CountA(rg.Columns(1)) nData = nData + 200 'Allow for servers whose software list exceeds 32,767 characters vData = rg.Value ReDim vResults(1 To nData, 1 To 2) For i = 1 To n If vData(i, 1) <> "" Then k = k + 1 vResults(k, 1) = vData(i, 1) If s <> "" Then If i > 1 Then vResults(k - 1, 2) = Left$(s, 32767) End If s = IIf(vData(i, 2) = "", "", vData(i, 2)) Else If vData(i, 2) <> "" Then If s = "" Then s = vData(i, 2) Else s = s & delimiter & vData(i, 2) End If End If End If 'Overflow occurs if you put more than 32,767 characters in a cell. This block allows up to 165 characters (plus delimiter) in next pass through loop. If Len(s) > 32600 Then If (i < n) And (vData(i + 1, 1) = "") Then vResults(k, 2) = s vResults(k + 1, 1) = vResults(k, 1) s = "" k = k + 1 End If End If Next If s <> "" Then vResults(k, 2) = Left$(s, 32767) rg.ClearContents rg.Resize(nData, 2).Value = vResults End Sub
The macro assumes your data starts in row 2 and that header labels are in row 1. It further assumes that you have no blank lines in your data, and that there are only two columns of data.
Your question said that you wanted to start with two columns of data in columns A and B, then end up with two columns of compacted results in columns A and B. That's what the macro does.
The third from the last statement in the macro deletes the existing data (except header labels). The next to last statement puts the compacted results starting in cell A2. If you want them moved elsewhere, that statement is easily changed.
I made 6270 copies of your data, filling the sheet past row 260000 and ran the macro. It completed work in less than a second.
- Brad YundtAug 25, 2022MVP"Subscript out of range" errors are commonly caused by code that references a range or worksheet by a specific name--and that nam e doesn't exist in your actual workbook. For example, code is looking for Worksheets("Sheet1") and you have one named "Sheet 1" with a space.
It really isn't possible to debug further without seeing a workbook that reproduces the error. I would then use the debugger to see which statement generates the error and what it is looking for. - srikanth75Aug 24, 2022Copper ContributorGetting runtime error '9'.
Subscript out of range - JayNixonJul 16, 2019Copper Contributor
Yeah, unfortunately I am working with such a large amount of data here that it doesn't want to cooperate by making it easy and convenient to read. There are thousands of servers and the software includes everything from Google Chrome to .net framework updates to security updates for various tools. But what I have now is the easiest to search through I believe. I can query the inventory for a server and then it will just show me the column(s) of data associated with it. From there I can just Ctrl+F to search more specifically. Thanks for trying to help me with my issue. I appreciate it. I have much to learn!!
- SergeiBaklanJul 16, 2019MVP
I see, thank you for the explanation. Perhaps servers in columns will be more compact and searchable, but it all depends on your concrete data.
- JayNixonJul 16, 2019Copper Contributor
I am importing this into a sharepoint webpage through the excel app and if I kept all the applications in columns then some of the servers would have 100+ columns. I am positive there is a better way to accomplish my task but am a new intern and I lack the knowledge to do so. :/
- SergeiBaklanJul 16, 2019MVP
If not a secret, what's the reason keep list of server software in so long strings instead of columns cell?
- JayNixonJul 16, 2019Copper Contributor
You have done it! Thank you for your dedication to this issue of mine. This works perfectly. Brad_Yundt
- Brad_YundtJul 16, 2019MVP
I revised the macro to allow up to 200 more rows of results in case of overflow, as well as up to 165 characters in next pass through the concatenation loop. When an overflow situation is detected, the server name will be repeated as often as needed to get all software names listed on additional rows.
Sub Sequelize() Dim rg As Range Dim delimiter As String, s As String Dim i As Long, k As Long, n As Long, nData As Long Dim vData As Variant, vResults As Variant delimiter = ", " Set rg = Range("A2").CurrentRegion Set rg = rg.Offset(1, 0).Resize(rg.Rows.Count - 1, rg.Columns.Count) n = rg.Rows.Count nData = Application.CountA(rg.Columns(1)) nData = nData + 200 'Allow for servers whose software list exceeds 32,767 characters vData = rg.Value ReDim vResults(1 To nData, 1 To 2) For i = 1 To n If vData(i, 1) <> "" Then k = k + 1 vResults(k, 1) = vData(i, 1) If s <> "" Then If i > 1 Then vResults(k - 1, 2) = Left$(s, 32767) End If s = IIf(vData(i, 2) = "", "", vData(i, 2)) Else If vData(i, 2) <> "" Then If s = "" Then s = vData(i, 2) Else s = s & delimiter & vData(i, 2) End If End If End If 'Overflow occurs if you put more than 32,767 characters in a cell. This block allows up to 165 characters (plus delimiter) in next pass through loop. If Len(s) > 32600 Then If (i < n) And (vData(i + 1, 1) = "") Then vResults(k, 2) = s vResults(k + 1, 1) = vResults(k, 1) s = "" k = k + 1 End If End If Next If s <> "" Then vResults(k, 2) = Left$(s, 32767) rg.ClearContents rg.Resize(nData, 2).Value = vResults End Sub
- JayNixonJul 16, 2019Copper Contributor
It sounds like it will work. I will be able to try it in a couple hours or so and will report back.
As far as the overflow, additional rows are acceptable.Brad_Yundt
- Brad_YundtJul 16, 2019MVP
Thanks for sending me the file. I can reproduce the problem with my Excel 2016/Office 365 64-bit.
Excel cells can hold a maximum of 32,767 characters. Your problem server has 86,510 characters worth of software. I am guessing an overflow occurs that results in the loss of your data.
To test this hypothesis, I modified the code to truncate the software list to the first 32,767 characters. Now the macro seems to work.
Sub Sequelize() Dim rg As Range Dim delimiter As String, s As String Dim i As Long, k As Long, n As Long, nData As Long Dim vData As Variant, vResults As Variant delimiter = ", " Set rg = Range("A2").CurrentRegion Set rg = rg.Offset(1, 0).Resize(rg.Rows.Count - 1, rg.Columns.Count) n = rg.Rows.Count nData = Application.CountA(rg.Columns(1)) vData = rg.Value ReDim vResults(1 To nData, 1 To 2) For i = 1 To n If vData(i, 1) <> "" Then k = k + 1 vResults(k, 1) = vData(i, 1) If s <> "" Then If i > 1 Then vResults(k - 1, 2) = Left$(s, 32767) End If s = IIf(vData(i, 2) = "", "", vData(i, 2)) Else If vData(i, 2) <> "" Then If s = "" Then s = vData(i, 2) Else s = s & delimiter & vData(i, 2) End If End If End If Next If s <> "" Then vResults(k, 2) = Left$(s, 32767) rg.ClearContents rg.Resize(nData, 2).Value = vResults End Sub
Please try running the revised macro on your full dataset. If it works, we can then shift discussion to how best to handle the text in the overflow. Perhaps additional columns or rows?
- JayNixonJul 16, 2019Copper ContributorI am currently running on Windows 7 and using MSOffice 365 ProPlus ver. 16.0.9126.2315
I have found that if I run the macro on smaller portions of data, it will run just fine. I am most the way through my document by now. - Brad_YundtJul 16, 2019MVP
I would like test my code on your actual workbook. It's OK if you replace all the data with the letter "x" as long as you can reproduce the problem. You can post a workbook in this thread, or you could email it to me at first initial last name at my ISP, which is alum dot mit dot edu. I would then like to try reproducing the problem. Fixing the problem is easy if I can reproduce it.
It's possible that there is a limitation of Excel VBA present in your version of Excel that is not in mine. All my testing so far has been on 64-bit Excel 2016/Office 365 running on Windows 10--but I have other versions available for testing (both Mac and Windows, 32-bit and 64-bit, 2007 to date).
Please tell me:
Which version of Excel do you use, Mac or Windows?
If Windows, is 2007, 2010, 2013, 2016 or 2019?
Is it 32-bit or 64-bit?
- JayNixonJul 16, 2019Copper Contributor
Here is a couple screenshots of the macro with a before and after running.
- JayNixonJul 16, 2019Copper Contributor
I formatted the empty cells and tested them with the =isblank and they all came up false, except for of course the cells with actual values. Although after deleting that =isblank column I still was unable to get the macro to run correctly. It is still deleting all the data in the worksheet. I am not sure what I am doing wrong. Will troubleshoot a bit more but I thought you might want an update. I also checked column B for blanks and came up with none as well. Thanks again Brad.
- Brad_YundtJul 15, 2019MVP
You can test whether a cell is truly blank using a formula like:
=ISBLANK(A2)
My guess is that many of your column A cells look blank but actually contain an invisible value, such as a single quote, space, non-breaking space, Tab or Carriage Return character.
- Brad_YundtJul 15, 2019MVP
Might you have empty strings or spaces in those "blank" cells? If you do, the macro won't work right.
- JayNixonJul 15, 2019Copper ContributorAlthough 90% or more are empty cells. I am not sure why they are registering as entries if they are empty.
- JayNixonJul 15, 2019Copper Contributor
Currently 235493 entries on column A. Brad_Yundt
- Brad_YundtJul 15, 2019MVP
If you select column A with your raw data, how many values are there? It should say something like Count: 6267 at the right of the status bar at the bottom of the application window.
- JayNixonJul 15, 2019Copper ContributorI feel like I am missing something very simple that is just going over my head here. My data headers "ComputerName"in column A and "Application" in column B are in row 1. Data starts in row 2. Column B has no blank cells but Column A has many blank cells. I had deleted the duplicate server names. To me, it looks almost identical to the sample I submitted.
For whatever reason, when I run the macro it just deletes all the data. I ran the script in the sample I gave you. It worked there. It will not work on my actual sheet. It hangs for a second or so then just deletes everything. I am sorry.
I wish I could understand this better and apologize if it feels like you are talking to a 5 year old! lol.