diff --git a/eeschema/annotate.cpp b/eeschema/annotate.cpp
index f3da8ed59a..a6b23af601 100644
--- a/eeschema/annotate.cpp
+++ b/eeschema/annotate.cpp
@@ -364,7 +364,7 @@ void SCH_EDIT_FRAME::AnnotateSymbols( SCH_COMMIT* aCommit, ANNOTATE_SCOPE_T  aAn
         wxString  newRef  = symbol->GetRef( sheet );
 
         if( symbol->GetUnitCount() > 1 )
-            newRef << LIB_SYMBOL::SubReference( symbol->GetUnitSelection( sheet ) );
+            newRef << symbol->SubReference( symbol->GetUnitSelection( sheet ) );
 
         wxString msg;
 
@@ -377,7 +377,7 @@ void SCH_EDIT_FRAME::AnnotateSymbols( SCH_COMMIT* aCommit, ANNOTATE_SCOPE_T  aAn
             {
                 msg.Printf( _( "Updated %s (unit %s) from %s to %s." ),
                             symbol->GetValueFieldText( true, sheet, false ),
-                            LIB_SYMBOL::SubReference( symbol->GetUnit(), false ),
+                            symbol->SubReference( symbol->GetUnit(), false ),
                             prevRef,
                             newRef );
             }
@@ -395,7 +395,7 @@ void SCH_EDIT_FRAME::AnnotateSymbols( SCH_COMMIT* aCommit, ANNOTATE_SCOPE_T  aAn
             {
                 msg.Printf( _( "Annotated %s (unit %s) as %s." ),
                             symbol->GetValueFieldText( true, sheet, false ),
-                            LIB_SYMBOL::SubReference( symbol->GetUnit(), false ),
+                            symbol->SubReference( symbol->GetUnit(), false ),
                             newRef );
             }
             else
diff --git a/eeschema/dialogs/dialog_lib_edit_pin_table.cpp b/eeschema/dialogs/dialog_lib_edit_pin_table.cpp
index ebd7044262..e49e44c4a9 100644
--- a/eeschema/dialogs/dialog_lib_edit_pin_table.cpp
+++ b/eeschema/dialogs/dialog_lib_edit_pin_table.cpp
@@ -220,7 +220,7 @@ public:
 
             case COL_UNIT:
                 if( pin->GetUnit() )
-                    val = LIB_SYMBOL::SubReference( pin->GetUnit(), false );
+                    val = LIB_SYMBOL::LetterSubReference( pin->GetUnit(), 'A' );
                 else
                     val = UNITS_ALL;
                 break;
@@ -426,7 +426,7 @@ public:
                 {
                     for( int i = 1; i <= m_symbol->GetUnitCount(); i++ )
                     {
-                        if( value == LIB_SYMBOL::SubReference( i, false ) )
+                        if( value == LIB_SYMBOL::LetterSubReference( i, 'A' ) )
                         {
                             pin->SetUnit( i );
                             break;
@@ -773,7 +773,7 @@ DIALOG_LIB_EDIT_PIN_TABLE::DIALOG_LIB_EDIT_PIN_TABLE( SYMBOL_EDIT_FRAME* parent,
     unitNames.push_back( UNITS_ALL );
 
     for( int i = 1; i <= aSymbol->GetUnitCount(); i++ )
-        unitNames.push_back( LIB_SYMBOL::SubReference( i, false ) );
+        unitNames.push_back( LIB_SYMBOL::LetterSubReference( i, 'A' ) );
 
     attr->SetEditor( new GRID_CELL_COMBOBOX( unitNames ) );
     m_grid->SetColAttr( COL_UNIT, attr );
diff --git a/eeschema/dialogs/dialog_symbol_properties.cpp b/eeschema/dialogs/dialog_symbol_properties.cpp
index 87f598e24c..bb708fe704 100644
--- a/eeschema/dialogs/dialog_symbol_properties.cpp
+++ b/eeschema/dialogs/dialog_symbol_properties.cpp
@@ -484,7 +484,7 @@ bool DIALOG_SYMBOL_PROPERTIES::TransferDataToWindow()
             if( m_symbol->HasUnitDisplayName( ii ) )
                 m_unitChoice->Append( m_symbol->GetUnitDisplayName( ii ) );
             else
-                m_unitChoice->Append( LIB_SYMBOL::SubReference( ii, false ) );
+                m_unitChoice->Append( m_symbol->SubReference( ii, false ) );
         }
 
         if( m_symbol->GetUnit() <= ( int )m_unitChoice->GetCount() )
diff --git a/eeschema/dialogs/panel_setup_formatting.cpp b/eeschema/dialogs/panel_setup_formatting.cpp
index 27c6db7c97..3474e2acff 100644
--- a/eeschema/dialogs/panel_setup_formatting.cpp
+++ b/eeschema/dialogs/panel_setup_formatting.cpp
@@ -64,23 +64,26 @@ void PANEL_SETUP_FORMATTING::onCheckBoxIref( wxCommandEvent& event )
 }
 
 
+int getRefStyleMenuIndex( int aSubpartIdSeparator, int aFirstSubpartId )
+{
+    // Reference style one of: "A" ".A" "-A" "_A" ".1" "-1" "_1"
+    switch( aSubpartIdSeparator )
+    {
+    default:
+    case 0:   return 0;
+    case '.': return aFirstSubpartId == '1' ? 4 : 1;
+    case '-': return aFirstSubpartId == '1' ? 5 : 2;
+    case '_': return aFirstSubpartId == '1' ? 6 : 3;
+    }
+}
+
+
 bool PANEL_SETUP_FORMATTING::TransferDataToWindow()
 {
     SCHEMATIC_SETTINGS& settings = m_frame->Schematic().Settings();
 
-    // Reference style one of: "A" ".A" "-A" "_A" ".1" "-1" "_1"
-    int refStyleSelection;
-
-    switch( LIB_SYMBOL::GetSubpartIdSeparator() )
-    {
-    default:
-    case 0:   refStyleSelection = 0; break;
-    case '.': refStyleSelection = LIB_SYMBOL::GetSubpartFirstId() == '1' ? 4 : 1; break;
-    case '-': refStyleSelection = LIB_SYMBOL::GetSubpartFirstId() == '1' ? 5 : 2; break;
-    case '_': refStyleSelection = LIB_SYMBOL::GetSubpartFirstId() == '1' ? 6 : 3; break;
-    }
-
-    m_choiceSeparatorRefId->SetSelection( refStyleSelection );
+    m_choiceSeparatorRefId->SetSelection( getRefStyleMenuIndex( settings.m_SubpartIdSeparator,
+                                                                settings.m_SubpartFirstId ) );
 
     m_textSize.SetUnits( EDA_UNITS::MILS );
     m_lineWidth.SetUnits( EDA_UNITS::MILS );
@@ -137,24 +140,16 @@ bool PANEL_SETUP_FORMATTING::TransferDataFromWindow()
     SCHEMATIC_SETTINGS& settings = m_frame->Schematic().Settings();
 
     // Reference style one of: "A" ".A" "-A" "_A" ".1" "-1" "_1"
-    int firstRefId, refSeparator;
-
     switch( m_choiceSeparatorRefId->GetSelection() )
     {
     default:
-    case 0: firstRefId = 'A'; refSeparator = 0; break;
-    case 1: firstRefId = 'A'; refSeparator = '.'; break;
-    case 2: firstRefId = 'A'; refSeparator = '-'; break;
-    case 3: firstRefId = 'A'; refSeparator = '_'; break;
-    case 4: firstRefId = '1'; refSeparator = '.'; break;
-    case 5: firstRefId = '1'; refSeparator = '-'; break;
-    case 6: firstRefId = '1'; refSeparator = '_'; break;
-    }
-
-    if( refSeparator != LIB_SYMBOL::GetSubpartIdSeparator() ||
-        firstRefId != LIB_SYMBOL::GetSubpartFirstId() )
-    {
-        LIB_SYMBOL::SetSubpartIdNotation( refSeparator, firstRefId );
+    case 0: settings.m_SubpartFirstId = 'A'; settings.m_SubpartIdSeparator = 0;   break;
+    case 1: settings.m_SubpartFirstId = 'A'; settings.m_SubpartIdSeparator = '.'; break;
+    case 2: settings.m_SubpartFirstId = 'A'; settings.m_SubpartIdSeparator = '-'; break;
+    case 3: settings.m_SubpartFirstId = 'A'; settings.m_SubpartIdSeparator = '_'; break;
+    case 4: settings.m_SubpartFirstId = '1'; settings.m_SubpartIdSeparator = '.'; break;
+    case 5: settings.m_SubpartFirstId = '1'; settings.m_SubpartIdSeparator = '-'; break;
+    case 6: settings.m_SubpartFirstId = '1'; settings.m_SubpartIdSeparator = '_'; break;
     }
 
     settings.m_DefaultTextSize = m_textSize.GetIntValue();
@@ -201,6 +196,9 @@ bool PANEL_SETUP_FORMATTING::TransferDataFromWindow()
 
 void PANEL_SETUP_FORMATTING::ImportSettingsFrom( SCHEMATIC_SETTINGS& aSettings )
 {
+    m_choiceSeparatorRefId->SetSelection( getRefStyleMenuIndex( aSettings.m_SubpartIdSeparator,
+                                                                aSettings.m_SubpartFirstId ) );
+
     m_textSize.SetValue( aSettings.m_DefaultTextSize );
     m_lineWidth.SetValue( aSettings.m_DefaultLineWidth );
     m_pinSymbolSize.SetValue( aSettings.m_PinSymbolSize );
diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp
index 35096716e2..bc7bd32b25 100644
--- a/eeschema/eeschema_config.cpp
+++ b/eeschema/eeschema_config.cpp
@@ -63,10 +63,6 @@ bool SCH_EDIT_FRAME::LoadProjectSettings()
     GetRenderSettings()->SetDashLengthRatio( settings.m_DashedLineDashRatio );
     GetRenderSettings()->SetGapLengthRatio( settings.m_DashedLineGapRatio );
 
-    // Verify some values, because the config file can be edited by hand, and have bad values:
-    LIB_SYMBOL::SetSubpartIdNotation( LIB_SYMBOL::GetSubpartIdSeparator(),
-                                      LIB_SYMBOL::GetSubpartFirstId() );
-
     BASE_SCREEN::m_DrawingSheetFileName = settings.m_SchDrawingSheetFileName;
 
     // Load the drawing sheet from the filename stored in BASE_SCREEN::m_DrawingSheetFileName.
diff --git a/eeschema/erc.cpp b/eeschema/erc.cpp
index be366c056d..f2f2c82451 100644
--- a/eeschema/erc.cpp
+++ b/eeschema/erc.cpp
@@ -277,7 +277,7 @@ void ERC_TESTER::TestTextVars( DS_PROXY_VIEW_ITEM* aDrawingSheet )
         {
             if( DS_DRAW_ITEM_TEXT* text = dynamic_cast<DS_DRAW_ITEM_TEXT*>( item ) )
             {
-                if( text->GetShownText( &sheet, true ).Matches( wxS( "*${*}*" ) ) )
+                if( text->GetShownText( true ).Matches( wxS( "*${*}*" ) ) )
                 {
                     std::shared_ptr<ERC_ITEM> erc = ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE );
                     erc->SetErrorMessage( _( "Unresolved text variable in drawing sheet" ) );
diff --git a/eeschema/lib_field.cpp b/eeschema/lib_field.cpp
index 053d992bce..79b8d7dac9 100644
--- a/eeschema/lib_field.cpp
+++ b/eeschema/lib_field.cpp
@@ -418,7 +418,7 @@ wxString LIB_FIELD::GetFullText( int unit ) const
     wxCHECK( GetParent(), text );
 
     if( GetParent()->IsMulti() )
-        text << LIB_SYMBOL::SubReference( unit );
+        text << LIB_SYMBOL::LetterSubReference( unit, 'A' );
 
     return text;
 }
diff --git a/eeschema/lib_item.cpp b/eeschema/lib_item.cpp
index 82a3f7d8fd..d394c7c089 100644
--- a/eeschema/lib_item.cpp
+++ b/eeschema/lib_item.cpp
@@ -52,7 +52,7 @@ void LIB_ITEM::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_IT
     if( m_unit == 0 )
         msg = _( "All" );
     else
-        msg = LIB_SYMBOL::SubReference( m_unit, false );
+        msg = LIB_SYMBOL::LetterSubReference( m_unit, 'A' );
 
     aList.emplace_back( _( "Unit" ), msg );
 
diff --git a/eeschema/lib_symbol.cpp b/eeschema/lib_symbol.cpp
index 462dbdec13..6d4ba8cd2e 100644
--- a/eeschema/lib_symbol.cpp
+++ b/eeschema/lib_symbol.cpp
@@ -37,16 +37,6 @@
 
 #include <memory>
 
-// the separator char between the subpart id and the reference
-// 0 (no separator) or '.' or some other character
-int LIB_SYMBOL::m_subpartIdSeparator = 0;
-
-// the ascii char value to calculate the subpart symbol id from the part number:
-// 'A' or '1' usually. (to print U1.A or U1.1)
-// if this a digit, a number is used as id symbol
-int LIB_SYMBOL::m_subpartFirstId = 'A';
-
-
 std::vector<SEARCH_TERM> LIB_SYMBOL::GetSearchTerms()
 {
     std::vector<SEARCH_TERM> terms;
@@ -548,7 +538,7 @@ LIB_SYMBOL_SPTR LIB_SYMBOL::GetRootSymbol() const
 
 wxString LIB_SYMBOL::GetUnitReference( int aUnit )
 {
-    return LIB_SYMBOL::SubReference( aUnit, false );
+    return LIB_SYMBOL::LetterSubReference( aUnit, 'A' );
 }
 
 
@@ -767,44 +757,28 @@ void LIB_SYMBOL::SetNormal()
 }
 
 
-wxString LIB_SYMBOL::SubReference( int aUnit, bool aAddSeparator )
+wxString LIB_SYMBOL::LetterSubReference( int aUnit, int aFirstId )
 {
-    wxString subRef;
+    // use letters as notation. To allow more than 26 units, the sub ref
+    // use one letter if letter = A .. Z or a ... z, and 2 letters otherwise
+    // first letter is expected to be 'A' or 'a' (i.e. 26 letters are available)
+    int      u;
+    wxString suffix;
 
-    if( aUnit < 1 )
-        return subRef;
-
-    if( m_subpartIdSeparator != 0 && aAddSeparator )
-        subRef << wxChar( m_subpartIdSeparator );
-
-    if( m_subpartFirstId >= '0' && m_subpartFirstId <= '9' )
+    do
     {
-        subRef << aUnit;
-    }
-    else
-    {
-        // use letters as notation. To allow more than 26 units, the sub ref
-        // use one letter if letter = A .. Z or a ... z, and 2 letters otherwise
-        // first letter is expected to be 'A' or 'a' (i.e. 26 letters are available)
-        int u;
-        wxString suffix;
+        u = ( aUnit - 1 ) % 26;
+        suffix = wxChar( aFirstId + u ) + suffix;
+        aUnit = ( aUnit - u ) / 26;
+    } while( aUnit > 0 );
 
-        do
-        {
-            u = ( aUnit - 1 ) % 26;
-            suffix = wxChar( m_subpartFirstId + u ) + suffix;
-            aUnit = ( aUnit - u ) / 26;
-        } while( aUnit > 0 );
-
-        subRef << suffix;
-    }
-
-    return subRef;
+    return suffix;
 }
 
 
 void LIB_SYMBOL::PrintBackground( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset,
-                        int aUnit, int aConvert, const LIB_SYMBOL_OPTIONS& aOpts, bool aDimmed )
+                                  int aUnit, int aConvert, const LIB_SYMBOL_OPTIONS& aOpts,
+                                  bool aDimmed )
 {
     /* draw background for filled items using background option
      * Solid lines will be drawn after the background
@@ -1740,19 +1714,6 @@ void LIB_SYMBOL::SetConversion( bool aSetConvert, bool aDuplicatePins )
 }
 
 
-void LIB_SYMBOL::SetSubpartIdNotation( int aSep, int aFirstId )
-{
-    m_subpartFirstId = 'A';
-    m_subpartIdSeparator = 0;
-
-    if( aSep == '.' || aSep == '-' || aSep == '_' )
-        m_subpartIdSeparator = aSep;
-
-    if( aFirstId == '1' && aSep != 0 )
-        m_subpartFirstId = aFirstId;
-}
-
-
 std::vector<LIB_ITEM*> LIB_SYMBOL::GetUnitDrawItems( int aUnit, int aConvert )
 {
     std::vector<LIB_ITEM*> unitItems;
diff --git a/eeschema/lib_symbol.h b/eeschema/lib_symbol.h
index a97970cd6b..30ff4042d0 100644
--- a/eeschema/lib_symbol.h
+++ b/eeschema/lib_symbol.h
@@ -598,41 +598,7 @@ public:
      */
     bool IsMulti() const { return m_unitCount > 1; }
 
-    /**
-     * @return the sub reference for symbol having multiple units per symbol.
-     * The sub reference identify the symbol (or unit)
-     * @param aUnit = the symbol identifier ( 1 to max count)
-     * @param aAddSeparator = true (default) to prepend the sub ref
-     *    by the separator symbol (if any)
-     * Note: this is a static function.
-     */
-    static wxString SubReference( int aUnit, bool aAddSeparator = true );
-
-    // Accessors to sub ref parameters
-    static int GetSubpartIdSeparator() { return m_subpartIdSeparator; }
-
-    /**
-     * Return a reference to m_subpartIdSeparator, only for read/save setting functions.
-     */
-    static int* SubpartIdSeparatorPtr() { return &m_subpartIdSeparator; }
-    static int GetSubpartFirstId() { return m_subpartFirstId; }
-
-    /**
-     * Return a reference to m_subpartFirstId, only for read/save setting functions.
-     */
-    static int* SubpartFirstIdPtr() { return &m_subpartFirstId; }
-
-    /**
-     * Set the separator char between the subpart id and the reference
-     * 0 (no separator) or '.' , '-' and '_'
-     * and the ascii char value to calculate the subpart symbol id from the symbol number:
-     * 'A' or '1' only are allowed. (to print U1.A or U1.1)
-     * if this is a digit, a number is used as id symbol
-     * Note also if the subpart symbol is a digit, the separator cannot be null.
-     * @param aSep = the separator symbol (0 (no separator) or '.' , '-' and '_')
-     * @param aFirstId = the Id of the first symbol ('A' or '1')
-     */
-    static void SetSubpartIdNotation( int aSep, int aFirstId );
+    static wxString LetterSubReference( int aUnit, int aFirstId );
 
     /**
      * Set or clear the alternate body style (DeMorgan) for the symbol.
@@ -804,12 +770,6 @@ private:
     wxArrayString       m_fpFilters;        ///< List of suitable footprint names for the
                                             ///<  symbol (wild card names accepted).
 
-    static int  m_subpartIdSeparator;       ///< the separator char between
-                                            ///< the subpart id and the reference like U1A
-                                            ///< ( m_subpartIdSeparator = 0 ) or U1.A or U1-A
-    static int  m_subpartFirstId;           ///< the ASCII char value to calculate the subpart
-                                            ///< symbol id from the symbol number: only 'A', 'a'
-                                            ///< or '1' can be used, other values have no sense.
     std::map<int, wxString> m_unitDisplayNames;
 };
 
diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp
index 5dd8f76510..fb2e79578e 100644
--- a/eeschema/sch_field.cpp
+++ b/eeschema/sch_field.cpp
@@ -249,7 +249,7 @@ wxString SCH_FIELD::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraT
             // For more than one part per package, we must add the part selection
             // A, B, ... or 1, 2, .. to the reference.
             if( parentSymbol->GetUnitCount() > 1 )
-                text << LIB_SYMBOL::SubReference( parentSymbol->GetUnit() );
+                text << parentSymbol->SubReference( parentSymbol->GetUnitSelection( aPath ) );
         }
     }
     else if( m_parent && m_parent->Type() == SCH_SHEET_T )
@@ -652,13 +652,14 @@ bool SCH_FIELD::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) co
         // symbols with multiple parts.
         if( aAuxData )
         {
-            text = parentSymbol->GetRef( (SCH_SHEET_PATH*) aAuxData );
+            SCH_SHEET_PATH* sheet = (SCH_SHEET_PATH*) aAuxData;
+            text = parentSymbol->GetRef( sheet );
 
             if( SCH_ITEM::Matches( text, aSearchData ) )
                 return true;
 
             if( parentSymbol->GetUnitCount() > 1 )
-                text << LIB_SYMBOL::SubReference( parentSymbol->GetUnit() );
+                text << parentSymbol->SubReference( parentSymbol->GetUnitSelection( sheet ) );
         }
     }
 
diff --git a/eeschema/sch_reference_list.cpp b/eeschema/sch_reference_list.cpp
index ecd245f7fb..996ff4c897 100644
--- a/eeschema/sch_reference_list.cpp
+++ b/eeschema/sch_reference_list.cpp
@@ -699,7 +699,7 @@ int SCH_REFERENCE_LIST::CheckAnnotation( ANNOTATION_ERROR_HANDLER aHandler )
             msg.Printf( _( "Error: symbol %s%s%s (unit %d) exceeds units defined (%d)" ),
                         m_flatList[ii].GetRef(),
                         tmp,
-                        LIB_SYMBOL::SubReference( m_flatList[ii].m_unit ),
+                        m_flatList[ii].GetSymbol()->SubReference( m_flatList[ii].GetUnit() ),
                         m_flatList[ii].m_unit,
                         m_flatList[ii].GetLibPart()->GetUnitCount() );
 
@@ -738,8 +738,8 @@ int SCH_REFERENCE_LIST::CheckAnnotation( ANNOTATION_ERROR_HANDLER aHandler )
             msg.Printf( _( "Duplicate items %s%s%s\n" ),
                         first.GetRef(),
                         tmp,
-                        first.GetLibPart()->GetUnitCount() > 1 ?
-                            LIB_SYMBOL::SubReference( first.m_unit ) : wxString( wxT( "" ) ) );
+                        first.GetLibPart()->GetUnitCount() > 1 ? first.GetSymbol()->SubReference( first.GetUnit() )
+                                                               : wxString( wxT( "" ) ) );
 
             aHandler( ERCE_DUPLICATE_REFERENCE, msg, &first, &m_flatList[ii+1] );
             error++;
@@ -761,12 +761,12 @@ int SCH_REFERENCE_LIST::CheckAnnotation( ANNOTATION_ERROR_HANDLER aHandler )
                 tmp2 = wxT( "?" );
 
             msg.Printf( _( "Differing unit counts for item %s%s%s and %s%s%s\n" ),
-                    first.GetRef(),
-                    tmp,
-                    LIB_SYMBOL::SubReference( first.m_unit ),
-                    second.GetRef(),
-                    tmp2,
-                    LIB_SYMBOL::SubReference( second.m_unit )  );
+                        first.GetRef(),
+                        tmp,
+                        first.GetSymbol()->SubReference( first.GetUnit() ),
+                        second.GetRef(),
+                        tmp2,
+                        first.GetSymbol()->SubReference( second.GetUnit() )  );
 
             aHandler( ERCE_DUPLICATE_REFERENCE, msg, &first, &second );
             error++;
@@ -779,11 +779,11 @@ int SCH_REFERENCE_LIST::CheckAnnotation( ANNOTATION_ERROR_HANDLER aHandler )
             msg.Printf( _( "Different values for %s%d%s (%s) and %s%d%s (%s)" ),
                         first.GetRef(),
                         first.m_numRef,
-                        LIB_SYMBOL::SubReference( first.m_unit ),
+                        first.GetSymbol()->SubReference( first.GetUnit() ),
                         first.m_value,
                         second.GetRef(),
                         second.m_numRef,
-                        LIB_SYMBOL::SubReference( second.m_unit ),
+                        first.GetSymbol()->SubReference( second.GetUnit() ),
                         second.m_value );
 
             aHandler( ERCE_DIFFERENT_UNIT_VALUE, msg, &first, &second );
diff --git a/eeschema/sch_reference_list.h b/eeschema/sch_reference_list.h
index 2563efa66e..ebe44b7a16 100644
--- a/eeschema/sch_reference_list.h
+++ b/eeschema/sch_reference_list.h
@@ -175,7 +175,7 @@ public:
             refNum << m_numRef;
 
         if( GetSymbol()->GetUnitCount() > 1 )
-            return GetRef() + refNum + LIB_SYMBOL::SubReference( GetUnit() );
+            return GetRef() + refNum + GetSymbol()->SubReference( GetUnit() );
         else
             return GetRef() + refNum;
     }
diff --git a/eeschema/sch_symbol.cpp b/eeschema/sch_symbol.cpp
index 7f47d8f755..a445698d77 100644
--- a/eeschema/sch_symbol.cpp
+++ b/eeschema/sch_symbol.cpp
@@ -481,7 +481,7 @@ int SCH_SYMBOL::GetUnitCount() const
 
 wxString SCH_SYMBOL::GetUnitDisplayName( int aUnit )
 {
-    wxCHECK( m_part, ( wxString::Format( _( "Unit %s" ), LIB_SYMBOL::SubReference( aUnit ) ) ) );
+    wxCHECK( m_part, ( wxString::Format( _( "Unit %s" ), SubReference( aUnit ) ) ) );
 
     return m_part->GetUnitDisplayName( aUnit );
 }
@@ -739,7 +739,7 @@ const wxString SCH_SYMBOL::GetRef( const SCH_SHEET_PATH* sheet, bool aIncludeUni
         if( instance.m_Path == path )
         {
             ref = instance.m_Reference;
-            subRef = LIB_SYMBOL::SubReference( instance.m_Unit );
+            subRef = SubReference( instance.m_Unit );
             break;
         }
     }
@@ -847,6 +847,15 @@ void SCH_SYMBOL::UpdatePrefix()
 }
 
 
+wxString SCH_SYMBOL::SubReference( int aUnit, bool aAddSeparator ) const
+{
+    if( SCHEMATIC* schematic = Schematic() )
+        return schematic->Settings().SubReference( aUnit, aAddSeparator );
+
+    return LIB_SYMBOL::LetterSubReference( aUnit, 'A' );
+}
+
+
 int SCH_SYMBOL::GetUnitSelection( const SCH_SHEET_PATH* aSheet ) const
 {
     KIID_PATH path = aSheet->Path();
@@ -1362,9 +1371,7 @@ bool SCH_SYMBOL::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, i
     }
     else if( token->IsSameAs( wxT( "UNIT" ) ) )
     {
-        int unit = GetUnitSelection( aPath );
-
-        *token = LIB_SYMBOL::SubReference( unit );
+        *token = SubReference( GetUnitSelection( aPath ) );
         return true;
     }
     else if( token->IsSameAs( wxT( "SYMBOL_LIBRARY" ) ) )
diff --git a/eeschema/sch_symbol.h b/eeschema/sch_symbol.h
index 2c6fa66910..989fed92db 100644
--- a/eeschema/sch_symbol.h
+++ b/eeschema/sch_symbol.h
@@ -278,6 +278,8 @@ public:
      */
     void UpdatePrefix();
 
+    wxString SubReference( int aUnit, bool aAddSeparator = true ) const;
+
     TRANSFORM& GetTransform() { return m_transform; }
     const TRANSFORM& GetTransform() const { return m_transform; }
 
diff --git a/eeschema/schematic_settings.cpp b/eeschema/schematic_settings.cpp
index 13deb9dd02..4ee4bb1308 100644
--- a/eeschema/schematic_settings.cpp
+++ b/eeschema/schematic_settings.cpp
@@ -235,10 +235,10 @@ SCHEMATIC_SETTINGS::SCHEMATIC_SETTINGS( JSON_SETTINGS* aParent, const std::strin
 
     // TODO(JE) should we keep these LIB_SYMBOL:: things around?
     m_params.emplace_back( new PARAM<int>( "subpart_id_separator",
-            LIB_SYMBOL::SubpartIdSeparatorPtr(), 0, 0, 126 ) );
+            &m_SubpartIdSeparator, 0, 0, 126 ) );
 
     m_params.emplace_back( new PARAM<int>( "subpart_first_id",
-            LIB_SYMBOL::SubpartFirstIdPtr(), 'A', '1', 'z' ) );
+            &m_SubpartFirstId, 'A', '1', 'z' ) );
 
     m_params.emplace_back( new PARAM<int>( "annotate_start_num",
             &m_AnnotateStartNum, 0 ) );
@@ -269,3 +269,22 @@ SCHEMATIC_SETTINGS::~SCHEMATIC_SETTINGS()
         m_parent = nullptr;
     }
 }
+
+
+wxString SCHEMATIC_SETTINGS::SubReference( int aUnit, bool aAddSeparator ) const
+{
+    wxString subRef;
+
+    if( aUnit < 1 )
+        return subRef;
+
+    if( m_SubpartIdSeparator != 0 && aAddSeparator )
+        subRef << wxChar( m_SubpartIdSeparator );
+
+    if( m_SubpartFirstId >= '0' && m_SubpartFirstId <= '9' )
+        subRef << aUnit;
+    else
+        subRef << LIB_SYMBOL::LetterSubReference( aUnit, m_SubpartFirstId );
+
+    return subRef;
+}
diff --git a/eeschema/schematic_settings.h b/eeschema/schematic_settings.h
index 38c14f0936..7c9ba78235 100644
--- a/eeschema/schematic_settings.h
+++ b/eeschema/schematic_settings.h
@@ -52,6 +52,9 @@ public:
 
     virtual ~SCHEMATIC_SETTINGS();
 
+    wxString SubReference( int aUnit, bool aAddSeparator = true ) const;
+
+public:
     // Default sizes are all stored in IU here, and in mils in the JSON file
 
     int       m_DefaultLineWidth;
@@ -66,6 +69,11 @@ public:
     int       m_ConnectionGridSize;     // usually 50mils (IU internally; mils in the JSON file)
 
     int       m_AnnotateStartNum;       // Starting value for annotation
+    int       m_SubpartIdSeparator;     // the separator char between the subpart id and the
+                                        //   reference like U1A, U1.A or U1-A
+    int       m_SubpartFirstId;         // the ASCII char value to calculate the subpart symbol
+                                        //   id from the symbol number: only 'A', 'a' or '1' can
+                                        //   be used, other values have no sense.
 
     bool      m_IntersheetRefsShow;
     bool      m_IntersheetRefsListOwnPage;
diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp
index f048a4c6f0..e89ddc5f2e 100644
--- a/eeschema/tools/sch_edit_tool.cpp
+++ b/eeschema/tools/sch_edit_tool.cpp
@@ -111,7 +111,7 @@ private:
         for( int ii = 0; ii < symbol->GetLibSymbolRef()->GetUnitCount(); ii++ )
         {
             wxString num_unit;
-            num_unit.Printf( _( "Unit %s" ), LIB_SYMBOL::SubReference( ii + 1, false ) );
+            num_unit.Printf( _( "Unit %s" ), symbol->SubReference( ii + 1, false ) );
 
             wxMenuItem* item = Append( ID_POPUP_SCH_SELECT_UNIT1 + ii, num_unit, wxEmptyString,
                                        wxITEM_CHECK );
diff --git a/qa/tests/eeschema/test_lib_part.cpp b/qa/tests/eeschema/test_lib_part.cpp
index 6213c21c17..cba6277510 100644
--- a/qa/tests/eeschema/test_lib_part.cpp
+++ b/qa/tests/eeschema/test_lib_part.cpp
@@ -346,11 +346,6 @@ BOOST_AUTO_TEST_CASE( SubReference )
             false,
             "AAZ",
         },
-        { // haven't configured a separator, so should be nothing
-            1,
-            true,
-            "A",
-        },
     };
 
     for( const auto& c : cases )
@@ -358,7 +353,7 @@ BOOST_AUTO_TEST_CASE( SubReference )
         BOOST_TEST_CONTEXT(
                 "Subref: " << c.m_index << ", " << c.m_addSep << " -> '" << c.m_expSubRef << "'" )
         {
-            const auto subref = m_part_no_data.SubReference( c.m_index, c.m_addSep );
+            const auto subref = LIB_SYMBOL::LetterSubReference( c.m_index, 'A' );
             BOOST_CHECK_EQUAL( subref, c.m_expSubRef );
         }
     }