Extract string from between 2 delimiters in a string (VBA)

Johnny C

Well-known Member
Joined
Nov 7, 2006
Messages
1,069
Office Version
  1. 365
Platform
  1. Windows
Hi

I've a function 'piece' that extracts text from between 2 delimiters in a string. E.g. text = "123-abc-567", piece(text,"-",2)="abc"

It currently goes through character by character looking for the delimiters.

Some time ago, someone mentioned on here that there was a function in XL2007 VBA that did it without the character loop.

I assume it's not worksheetfunction.find; can anyone tell me what it is?

(here's my code)
Code:
Function piece(Searchstring As String, Separator As String, IndexNum As Integer) As String
Dim i, SepCount, SepLen, StartPos, EndPos As Integer
Dim TestStr As String
SepLen = Len(Separator)
SepCount = 0
StartPos = 0
EndPos = 0
For i = 1 To Len(Searchstring) - (SepLen - 1)
    TestStr = Mid(Searchstring, i, SepLen)
    If TestStr = Separator Then
        SepCount = SepCount + 1
        If SepCount = IndexNum - 1 Then StartPos = i + 1
        If SepCount = IndexNum Then EndPos = i
    End If
Next i
If StartPos = 0 And EndPos = 0 Then
    piece = ""
    Exit Function
End If
If StartPos = 0 Then StartPos = 1
If EndPos = 0 Then EndPos = Len(Searchstring) + 1
piece = Mid(Searchstring, StartPos, EndPos - StartPos)
End Function
 
Thank you! Thank you! Thank you! You are the best. This works exactly how I wanted it to, and it is far more clear than the mess I came up with. :-)

Thanks again.

BWL
 
Upvote 0

Excel Facts

Test for Multiple Conditions in IF?
Use AND(test, test, test, test) or OR(test, test, test, ...) as the logical_test argument of IF.
Hi,
I have a similar puzzle but it's much more of a beast.
I received a download of data that was supposed to be in XML format, but that doesn't appear to be the case.
I've tried using the XML functionality in Excel and it just crashes.

Some of the data is in a format that should be easy to manage:[TABLE="width: 1790"]
<tbody>[TR]
[TD="width: 1790"] <NamePrefix>MR</NamePrefix>
But in some cases I have multiple values that need to be extracted from a single line, and there is no standard to the length. In these, I need a column with the title, and another column with the value:
[TABLE="width: 1790"]
<tbody>[TR]
[TD="width: 1790"] <TPA_Identity ClientCode="TN" ClientContextCode="CON" UniqueID="123456789" ProfileTypeCode="TVL" ProfileName="SMITH/BOB" DomainID="A1AA" />[/TD]
[/TR]
</tbody>[/TABLE]
[/TD]
[/TR]
</tbody>[/TABLE]

I have about 10000 profiles, each separated by a blank row.
In a perfect world, I would like to create a new tab with each column header, then have a macro that loops through each profile, extracts the appropriate values and enters them into the columns on the second tab.
I've done some basic VBA programming but this one is way over my head.



[TABLE="width: 1790"]
<colgroup><col></colgroup><tbody>[TR]
[TD]<?xml version="1.0" encoding="utf-16"?>[/TD]
[/TR]
[TR]
[TD]<TEST_OTA_ProfileReadRS xmlns:xsi="http://www.w3.test/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="6.42">[/TD]
[/TR]
[TR]
[TD] <ResponseMessage xmlns="http://wwwtest.com/eps/schemas">[/TD]
[/TR]
[TR]
[TD] <Success />[/TD]
[/TR]
[TR]
[TD] </ResponseMessage>[/TD]
[/TR]
[TR]
[TD] <Profile CreateDateTime="2018-05-16T19:47:40.195Z" UpdateDateTime="2018-05-16T19:47:40.195Z" PrimaryLanguageIDCode="EN-US" xmlns="http://www.test.com/eps/schemas">[/TD]
[/TR]
[TR]
[TD] <TPA_Identity ClientCode="TN" ClientContextCode="CON" UniqueID="123456789" ProfileTypeCode="TVL" ProfileName="SMITH/BOB" DomainID="A1AA" />[/TD]
[/TR]
[TR]
[TD] <Traveler>[/TD]
[/TR]
[TR]
[TD] <Customer BirthDate="1999-01-01" GenderCode="M">[/TD]
[/TR]
[TR]
[TD] <PersonName LanguageIDCode="EN-US" OrderSequenceNo="1">[/TD]
[/TR]
[TR]
[TD] <NamePrefix>MR</NamePrefix>[/TD]
[/TR]
[TR]
[TD] <GivenName>SMITH</GivenName>[/TD]
[/TR]
[TR]
[TD] <MiddleName>JIM</MiddleName>[/TD]
[/TR]
[TR]
[TD] <SurName>BOB</SurName>[/TD]
[/TR]
[TR]
[TD] </PersonName>[/TD]
[/TR]
[TR]
[TD] <Telephone LocationTypeCode="HOM" OrderSequenceNo="1" PNRTelephoneTagIndicator="Y">[/TD]
[/TR]
[TR]
[TD] <FullPhoneNumber>555-555-5555</FullPhoneNumber>[/TD]
[/TR]
[TR]
[TD] </Telephone>[/TD]
[/TR]
[TR]
[TD] <Telephone LocationTypeCode="BUS" OrderSequenceNo="1" PNRTelephoneTagIndicator="Y">[/TD]
[/TR]
[TR]
[TD] <FullPhoneNumber>555 666 9999 123456</FullPhoneNumber>[/TD]
[/TR]
[TR]
[TD] </Telephone>[/TD]
[/TR]
[TR]
[TD] <Telephone LocationTypeCode="MOB" OrderSequenceNo="1" PNRTelephoneTagIndicator="Y">[/TD]
[/TR]
[TR]
[TD] <FullPhoneNumber>CA*1*888-666-1234</FullPhoneNumber>[/TD]
[/TR]
[TR]
[TD] </Telephone>[/TD]
[/TR]
[TR]
[TD] <Email EmailTypeCode="BUS" EmailAddress="BOB.SMITH@TEST.COM" OrderSequenceNo="1" />[/TD]
[/TR]
[TR]
[TD] <RelatedIndividual RelationType="AU" OrderSequenceNo="1">[/TD]
[/TR]
[TR]
[TD] <GivenName>BOBBY</GivenName>[/TD]
[/TR]
[TR]
[TD] <SurName>SMITHY</SurName>[/TD]
[/TR]
[TR]
[TD] <Telephone>[/TD]
[/TR]
[TR]
[TD] <FullPhoneNumber>555 418 1234</FullPhoneNumber>[/TD]
[/TR]
[TR]
[TD] </Telephone>[/TD]
[/TR]
[TR]
[TD] <Email EmailAddress="BOBBY.SMITHY@TEST.COM" />[/TD]
[/TR]
[TR]
[TD] </RelatedIndividual>[/TD]
[/TR]
[TR]
[TD] <Document DocTypeCode="OTHR" OrderSequenceNo="1" IsUsedForSecureFlightRules="Y">[/TD]
[/TR]
[TR]
[TD] <DocHolder>[/TD]
[/TR]
[TR]
[TD] <NamePrefix>MR</NamePrefix>[/TD]
[/TR]
[TR]
[TD] <SurName>SMITH</SurName>[/TD]
[/TR]
[TR]
[TD] <GivenName>BOB</GivenName>[/TD]
[/TR]
[TR]
[TD] <MiddleName>JIM</MiddleName>[/TD]
[/TR]
[TR]
[TD] </DocHolder>[/TD]
[/TR]
[TR]
[TD] </Document>[/TD]
[/TR]
[TR]
[TD] <EmploymentInfo OrderSequenceNo="1" InformationText="BOB.SMITH@TEST.COM">[/TD]
[/TR]
[TR]
[TD] <EmployeeInfo Division="TEST DIVISION" Company="TEST COMPANY" />[/TD]
[/TR]
[TR]
[TD] </EmploymentInfo>[/TD]
[/TR]
[TR]
[TD] </Customer>[/TD]
[/TR]
[TR]
[TD] <PrefCollections>[/TD]
[/TR]
[TR]
[TD] <AirlinePref TripTypeCode="CP" OrderSequenceNo="1">[/TD]
[/TR]
[TR]
[TD] <AirlineSeatPref>[/TD]
[/TR]
[TR]
[TD] <SeatInfo SeatPreferenceCode="NSNO" />[/TD]
[/TR]
[TR]
[TD] </AirlineSeatPref>[/TD]
[/TR]
[TR]
[TD] </AirlinePref>[/TD]
[/TR]
[TR]
[TD] <HotelPref TripTypeCode="CP" OrderSequenceNo="1" />[/TD]
[/TR]
[TR]
[TD] <VehicleRentalPref TripTypeCode="CP" OrderSequenceNo="1" />[/TD]
[/TR]
[TR]
[TD] <RailPref TripTypeCode="CP" OrderSequenceNo="1" />[/TD]
[/TR]
[TR]
[TD] </PrefCollections>[/TD]
[/TR]
[TR]
[TD] <TPA_Extensions>[/TD]
[/TR]
[TR]
[TD] <AssociatedFilters FilterID="12345678" FilterName="MOVE ALL" ClientCode="TN" ClientContextCode="MYS" DomainID="A1AA" OrderSequenceNo="1" CreateDateTime="2016-09-16T18:10:39.102Z" UpdateDateTime="2017-12-11T18:02:56.815Z" TemplateInheritInd="Y" />[/TD]
[/TR]
[TR]
[TD] <CustomDefinedData CustomFieldCode="OTH" Value="" DomainID="A1AA" OrderSequenceNo="2" InformationText="Language_1" />[/TD]
[/TR]
[TR]
[TD] <CustomDefinedData CustomFieldCode="OTH" Value="" DomainID="A1AA" OrderSequenceNo="3" InformationText="Agent_1" />[/TD]
[/TR]
[TR]
[TD] <CustomDefinedData CustomFieldCode="OTH" Value="DEFAULT TRAVEL CLASS" DomainID="A1AA" OrderSequenceNo="1" InformationText="RULE_CLASS_NAME" />[/TD]
[/TR]
[TR]
[TD] </TPA_Extensions>[/TD]
[/TR]
[TR]
[TD] </Traveler>[/TD]
[/TR]
[TR]
[TD] <Association AssociationID="123455" DomainID="T5OI" ClientCode="TN" AssociationDescription="TEMPLATE_1" AssociationName="TESTTEMPLATE" ClientContextCode="MYS" ProfileTypeCode="TVL" CreateDateTime="2016-09-16T18:41:55.519Z" UpdateDateTime="2016-09-16T18:41:55.519Z" />[/TD]
[/TR]
[TR]
[TD] </Profile>[/TD]
[/TR]
[TR]
[TD]</Test_OTA_ProfileReadRS>


Divided into columns like this:

[TABLE="width: 569"]
<colgroup><col><col><col><col><col><col></colgroup><tbody>[TR]
[TD]Unique ID[/TD]
[TD]Profile Name[/TD]
[TD]Customer BirthDate[/TD]
[TD]Gender[/TD]
[TD]HOM Phone[/TD]
[TD]BUS Phone[/TD]
[/TR]
[TR]
[TD="align: right"]123456789[/TD]
[TD]SMITH/BOB[/TD]
[TD]1999-01-01[/TD]
[TD]M[/TD]
[TD]555-555-5555[/TD]
[TD]555 666 9999 123456[/TD]
[/TR]
</tbody>[/TABLE]


Thanks in advance for your help!
CL[/TD]
[/TR]
</tbody>[/TABLE]
 
Upvote 0
The reason your code was falling over is that the lines look back to front, also you're not incrementing i (unless you deleted some code):

Mid(s, k + 1, [j - k - 1]) = piece <--error occurs on this line
piece = wke.Cells(i, "G").Value

You can't cut text into a string like that. I think what you meant was

Code:
piece = Mid(s, k + 1, [j - k - 1])    
wke.Cells(i, "G").Value = piece
i = i + 1

or just

Code:
wke.Cells(i, "G").Value = Mid(s, k + 1, [j - k - 1])
i = i + 1
 
Upvote 0

Forum statistics

Threads
1,224,537
Messages
6,179,408
Members
452,912
Latest member
alicemil

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top