+ Reply to Thread
Results 1 to 4 of 4

sorting an order of contract type

Hybrid View

  1. #1
    Valued Forum Contributor Sean Thomas's Avatar
    Join Date
    03-25-2012
    Location
    HerneBay, Kent, UK
    MS-Off Ver
    Excel 2007,2016
    Posts
    971

    sorting an order of contract type

    Hi,
    I have a situation that I would like to see if anyone has any good ideas on a solution.
    Basically I have 2 sheets
    In Contract (these are sites with a current contract)
    Terminated (previous contracts)

    Sites may have 3 contracts in place ie A, Peugeot, Citroen
    The contracts available are in order of priority:
    ARC
    A
    B
    VM but will be listed in the 2 sheets as either Peugeot or Citroen
    NRG
    NS
    Not contracted

    What I need to do is create sheet3 which is a list of unique sites based on site id and a history of their contracts

    ie Site name, site id, earliest contract date, contract type, next contract date & contract type, next contract date & contract type, next contract date & contract type

    so say site Rep1 was originally contract Peugeot 01/01/14 to 01/01/17, but also took on a contract A on 01/04/16 to 01/01/17 then they would read on sheet3:
    Rep1, Rep1 site id, 01/01/14, VM, 01/04/16, A, 01/01/17, Not Contracted

    and say site Rep2 was originally contract B 01/01/14 to 31/01/15, and then not conctracted until they took on contract NRG 01/05/16 to 01/01/17 then they would read on sheet3:
    Rep2, Rep2 site id, 01/01/14, B, 01/05/16, NRG, 01/01/17, Not Contracted

    I have attached a sample set of data so hopefully you can get the picture.

    The idea is i have a set of data going back to 01/01/14 to present date and need to pull the data out based on their site id and then produce a report sumarising the data based on the the various type of contracts.
    so in that time one site may have been a contract A, VM and also not contracted. but their data will be split up. This part i have already sorted by using the table in sheet 3 as it will look up the site id and then look up the date and find the nearest date and return the contract type. I do not expect for a site to have more than 4 contract periods hence only 4 colums sets used.

    I was thinking of first off getting a list of unique ids from the first 2 sheets, then running through each site id, pulling the relevant contract types and dates, sorting them by date order and then contract type and then checking through the list and putting them in order in the chart in sheet 3.

    Has anyone got any fancy ideas on how to enumerate this info quickly?
    Attached Files Attached Files
    Regards
    Sean

    Please add to my reputation if you think i helped
    (click on the star below the post)
    Mark threads as "Solved" if you have your answer
    (Thread Tools->Mark thread as Solved)
    Use code tags when posting your VBA code:
    [code] Your code here [code]
    Please supply a workbook containing example Data:
    It makes its easier to answer your problem & saves time!

  2. #2
    Forum Expert
    Join Date
    01-23-2013
    Location
    USA
    MS-Off Ver
    Microsoft 365 aka Office 365
    Posts
    3,863

    Re: sorting an order of contract type

    Hi Sean,

    The attached file contains the following VBA Code. I had one problem, probably because I did not understand your requirements. I put down 'VM' twice where you have it only once.

    The algorithm I used was:
    Possible Solution Algorithm:
    a. Create a list of items in a string: Site ID, Start Date (as yyyymmdd), Coded Priority, End Date (as yyyymmdd)
    e.g. '1234 , 20140101, BBA , 20170301'
    b. Sort the Strings
    c. Put the Strings in the Output List (removing the first 2 characters) of the encoded value.
    d. Put the Latest End Date for a 'Site Id' as 'Not Contracted'

    Encode the Site Ids in Priority order as:
    AAARC
    BBA
    CCB
    DDVM
    EENRG
    FFNS
    GGNot contracted

    Option Explicit
    
    Sub ClearDataAreaInSheetOutout()
      'This Clears the 'Output Sheet'
    
      Dim ws As Worksheet
    
      Set ws = Sheets("Outout")
      ws.Range("C2:Z" & Rows.Count).Clear
    
      'Clear objet pointers
      Set ws = Nothing
    
    End Sub
    
    
    Function EncodeContractId(sOriginalId As String) As String
      'This encodes 'Contract Ids' according to priority
      '
      'The contracts available are in order of priority:
      'Arc
      'A
      'B
      'VM but will be listed in the 2 sheets as either Peugeot or Citroen
      'NRG
      'NS
      'Not contracted
      
      
      Dim sLocalId As String
      Dim sEncodedValue As String
      
      'Create an UPPER case copy of the 'Original Id' (removed leading/trailing spaces)
      sLocalId = UCase(Trim(sOriginalId))
      
      Select Case sLocalId
      
        Case "ARC"
          sEncodedValue = "AA" & sOriginalId
      
        Case "A"
          sEncodedValue = "BB" & sOriginalId
      
        Case "B"
          sEncodedValue = "CC" & sOriginalId
      
        Case "PEUGEOT", "CITROEN"
          sEncodedValue = "DD" & "VM"
      
        Case "NRG"
          sEncodedValue = "EE" & sOriginalId
      
        Case "NS"
          sEncodedValue = "FF" & sOriginalId
      
        Case "Not Contracted"
          sEncodedValue = "GG" & sOriginalId
      
      End Select
      
      'Set the return value
      EncodeContractId = sEncodedValue
    
    End Function
    
    
    Sub SortContracts()
      'This sorts the Contracts and puts the Data in the 'Output Area'
    
      Dim ws As Worksheet
      Dim myEndDate As Date
      Dim myEndDateLatest As Date
      Dim myStartDate As Date
    
      Dim i As Long
      Dim iLastColumn As Long
      Dim iLastRow As Long
      Dim iMaxArrayItemCount As Long
      Dim iRow As Long
      
      Dim a() As String
      Dim sArray() As String
      Dim sConcatenation As String
      Dim sContractId As String
      Dim sEndDate As String
      Dim sSiteIdPrevious As String
      Dim sSiteId As String
      Dim sStartDate As String
      Dim sValue As String
      
      
      'Initialize the Array
      iMaxArrayItemCount = 0
      ReDim sArray(1 To 1)
      
      'Clear the Output Data Area
      Call ClearDataAreaInSheetOutout
      
      ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      'Read and Encode the Data from Sheet 'Contract'
      ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      
      'Create the Worksheet Object
      Set ws = Sheets("In Contract")
      
      'Find the Last Row on the Sheet
      iLastRow = ws.Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
    
      'Put the Data in the Array
      For iRow = 2 To iLastRow
      
        'Read the Data
        sSiteId = Trim(ws.Cells(iRow, "B").Value)
        sContractId = Trim(ws.Cells(iRow, "C").Value)
        sStartDate = Trim(ws.Cells(iRow, "D").Value)
        sEndDate = Trim(ws.Cells(iRow, "E").Value)
      
        'Replace the 'Contract Id' with an encoded 'Contract Id'
        'Replace the 'Start Date' with an 'yyyymmdd' string
        sContractId = EncodeContractId(sContractId)
        sStartDate = Format(sStartDate, "yyyymmdd")
        sEndDate = Format(sEndDate, "yyyymmdd")
        
        'Create the composite string and put the value in the array
        sConcatenation = sSiteId & " , " & sStartDate & " , " & sContractId & " , " & sEndDate
        iMaxArrayItemCount = iMaxArrayItemCount + 1
        ReDim Preserve sArray(1 To iMaxArrayItemCount)
        sArray(iMaxArrayItemCount) = sConcatenation
      
      Next iRow
      
      
      
      ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      'Read and Encode the Data from Sheet 'Terminated'
      ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      Set ws = Sheets("Terminated")
      
      'Find the Last Row on the Sheet
      iLastRow = ws.Cells.Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
    
      'Put the Data in the Array
      For iRow = 2 To iLastRow
      
        'Read the Data
        sSiteId = Trim(ws.Cells(iRow, "B").Value)
        sContractId = Trim(ws.Cells(iRow, "C").Value)
        sStartDate = Trim(ws.Cells(iRow, "D").Value)
        sEndDate = Trim(ws.Cells(iRow, "E").Value)
      
        'Replace the 'Contract Id' with an encoded 'Contract Id'
        'Replace the 'Start Date' with an 'yyyymmdd' string
        sContractId = EncodeContractId(sContractId)
        sStartDate = Format(sStartDate, "yyyymmdd")
        sEndDate = Format(sEndDate, "yyyymmdd")
        
        'Create the composite string and put the value in the array
        sConcatenation = sSiteId & " , " & sStartDate & " , " & sContractId & " , " & sEndDate
        iMaxArrayItemCount = iMaxArrayItemCount + 1
        ReDim Preserve sArray(1 To iMaxArrayItemCount)
        sArray(iMaxArrayItemCount) = sConcatenation
      
      Next iRow
        
      
      ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      'Sort the Data
      ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      Call LjmBubbleSortString(sArray)
      
      ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      'Put the Data in Sheet 'Outout'
      ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      Set ws = Sheets("Outout")
    
      For i = 1 To iMaxArrayItemCount
      
        'Get the Data
        'Parse the Data
        sValue = sArray(i)
        Call LjmParseString(sValue, a)
        
        'Get the values from the parsed string (remove leading/trailing spaces)
        sSiteId = Trim(a(0))
        sStartDate = Trim(a(1))
        sContractId = Trim(a(2))
        sEndDate = Trim(a(3))
        
        'Decode the 'Contract Id' and the 'Date'
        sContractId = Right(sContractId, Len(sContractId) - 2)
        myStartDate = yyyymmddToDate(sStartDate)
        myEndDate = yyyymmddToDate(sEndDate)
        
        'Debug.Print i, sSiteId, sContractId, myStartDate, myEndDate
        
        'Output 'Not Contracted' for the Latest 'End Date'
        If i > 1 And sSiteId <> sSiteIdPrevious Then
        
          ws.Cells(iRow, iLastColumn).Offset(0, 3).Value = myEndDateLatest
          ws.Cells(iRow, iLastColumn).Offset(0, 4).Value = "Not contracted"
        
          'Initialize the 'Latest' End Date for the next 'Site Id'
          myEndDateLatest = CDate("January 1, 2000")
        End If
        
        
        'Find the row in Colum 'B' that contains the 'Site Id' in Column 'B'
        'Find the 'Last Column' used in the row
        iRow = ws.Range("B:B").Find(What:=sSiteId, SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
        iLastColumn = ws.Rows(iRow).Find(What:="*", SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column
    
        'Put the data in the SpreadSheet
        ws.Cells(iRow, iLastColumn).Offset(0, 1).Value = myStartDate
        ws.Cells(iRow, iLastColumn).Offset(0, 2).Value = sContractId
        
        'Save the 'Latest' End Date for this 'Site Id'
        If myEndDate > myEndDateLatest Then
          myEndDateLatest = myEndDate
        End If
        
        'Save the 'Site Id'
        sSiteIdPrevious = sSiteId
        
      Next i
    
      'Output the 'Last' 'Not Contracted'
      ws.Cells(iRow, iLastColumn).Offset(0, 3).Value = myEndDateLatest
      ws.Cells(iRow, iLastColumn).Offset(0, 4).Value = "Not contracted"
    
    
      ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      'Termination
      ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
      
      'Clear object pointers
      Set ws = Nothing
    
    End Sub
    
    
    Sub LjmBubbleSortString(ByRef myArray() As String)
      'This sorts a string array in ascending order using a 'Bubble Sort' algorithm
         
      Dim iFirst As Long
      Dim iLast As Long
      Dim i As Long
      Dim j As Long
      Dim sTemp As String
         
      'Get the start and end indices
      iFirst = LBound(myArray)
      iLast = UBound(myArray)
        
      'Sort
      For i = iFirst To iLast - 1
        For j = i + 1 To iLast
          If myArray(i) > myArray(j) Then
            sTemp = myArray(j)
            myArray(j) = myArray(i)
            myArray(i) = sTemp
          End If
       Next j
     Next i
         
    End Sub
    
    Function LjmParseString(InputString As String, ByRef sArray() As String) As Long
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    '
    ' This parses a comma delimited string into an array of tokens.
    ' Leading and trailing spaces are stripped from the string in the process.
    '
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    
      Dim i As Integer
      Dim LastNonEmpty As Integer
      Dim iSplitIndex As Integer
    
     'Initialization
      LastNonEmpty = -1
      
      'Split the string into tokens
      sArray = Split(InputString, ",")
      iSplitIndex = UBound(sArray)
    
     'Remove the null tokens
      For i = 0 To iSplitIndex
    
        If sArray(i) <> "" Then
           'Get rid of all the whitespace
            LastNonEmpty = LastNonEmpty + 1
            sArray(LastNonEmpty) = sArray(i)
        End If
      Next i
    
    
     'Return the number of indices
      LjmParseString = LastNonEmpty
      
    End Function
    
    Function yyyymmddToDate(syyyymmdd As String) As Date
      'This converts a date string of the form 'yyyymmdd' to an Excel Date
      '
      'NOTE: The year must be 1904 >= year <= 2037
    
      Dim myDate As Date
      
      Dim iYear As Long
      
      Dim sYear As String
      Dim sMonth As String
      Dim sDayOfMonth As String
      
      If Len(syyyymmdd) = 8 And IsNumeric(syyyymmdd) Then
        sYear = Mid(syyyymmdd, 1, 4)
        sMonth = Mid(syyyymmdd, 5, 2)
        sDayOfMonth = Mid(syyyymmdd, 7, 2)
        
        iYear = CInt(sYear)
        If iYear >= 1904 And iYear <= 2037 Then
          myDate = DateSerial(iYear, CInt(sMonth), CInt(sDayOfMonth))
        End If
        
      End If
    
      'Set the return value
      yyyymmddToDate = myDate
    
    End Function
    Lewis
    Attached Files Attached Files

  3. #3
    Valued Forum Contributor Sean Thomas's Avatar
    Join Date
    03-25-2012
    Location
    HerneBay, Kent, UK
    MS-Off Ver
    Excel 2007,2016
    Posts
    971

    Re: sorting an order of contract type

    Lewis you are a star!
    I wasn't expecting you to write the code for me, I was mainly after some different ideas.
    But you have provided a perfect solution which I can use - outstanding!

    I have made one alteration though.
    Because both the Peugeot & Citroen contracts will always be the same dates and assigned to an overview contract name VM, they only need one entry.
    So I have just checked to see if the new string is different to the previous string and if so move onto to the next one

    sValue = sArray(i)
        'check if string is the same as the last one to avoid duplicating VM
        If sValue <> oldValue Then
            oldValue = sValue
    This seems to work perfectly.
    I will try it out on my full data set to see how it operates
    Thanks again, glad to see you are still writing superb code that I can only hope to match one day.

    I have finally secured a role where I can use my excel skills, so I'm slowly refreshing my skill set as I have got a little rusty the last year or so as I haven't been doing that much.

  4. #4
    Forum Expert
    Join Date
    01-23-2013
    Location
    USA
    MS-Off Ver
    Microsoft 365 aka Office 365
    Posts
    3,863

    Re: sorting an order of contract type

    Hi Sean,

    It's good to see you active again. I was going to suggest the fix you posted if couldn't fix it yourself. I figured I had to let you have a little fun.

    Lewis

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Replies: 7
    Last Post: 03-20-2016, 12:06 PM
  2. how to sum all the contract until end of the contract period
    By neskafeice in forum Excel Formulas & Functions
    Replies: 2
    Last Post: 10-01-2012, 07:37 AM
  3. Special Type of Sorting
    By lildog44 in forum Excel Formulas & Functions
    Replies: 2
    Last Post: 09-06-2012, 12:35 PM
  4. Replies: 1
    Last Post: 01-06-2012, 05:55 PM
  5. Vlookup codes based type of contract
    By foxhound82 in forum Excel General
    Replies: 5
    Last Post: 02-10-2011, 11:09 AM
  6. sorting in order
    By ceemo in forum Excel Formulas & Functions
    Replies: 13
    Last Post: 09-06-2005, 12:05 PM
  7. sorting in order
    By ceemo in forum Excel Formulas & Functions
    Replies: 0
    Last Post: 06-30-2005, 08:20 AM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

Search Engine Friendly URLs by vBSEO 3.6.0 RC 1