diff --git a/soitool/coder.py b/soitool/coder.py
index e900cc3e8042f41c0a168c49d41fdd28b4e1fcf9..3439f53eadb9d14e077f1455812e99d89776f345 100644
--- a/soitool/coder.py
+++ b/soitool/coder.py
@@ -6,7 +6,7 @@ import string
 import secrets
 
 
-def get_code(code_length, mode="ascii", space_interval=0):
+def get_code(code_length, mode="ascii", space_interval=0, space_amount=1):
     """
     Generate a single random code.
 
@@ -19,6 +19,8 @@ def get_code(code_length, mode="ascii", space_interval=0):
         combination of letters and digits, by default 'ascii'.
     space_interval : int
         Spaces will be inserted to code each interval if not 0, by default 0.
+    space_amount : int
+        Amount of spaces per interval, by default 1.
 
     Return
     ------
@@ -52,12 +54,14 @@ def get_code(code_length, mode="ascii", space_interval=0):
 
     # Add spaces to code if interval is given
     if space_interval > 0:
-        code = insert_spaces(code, space_interval)
+        code = insert_spaces(code, space_interval, space_amount)
 
     return code
 
 
-def get_code_set(count, code_length, mode="ascii", space_interval=0):
+def get_code_set(
+    count, code_length, mode="ascii", space_interval=0, space_amount=1
+):
     """
     Generate a set of unique, random codes.
 
@@ -72,6 +76,8 @@ def get_code_set(count, code_length, mode="ascii", space_interval=0):
         for combination of letters and digits.
     space_interval : int
         Spaces will be inserted to code each interval if not 0, by default 0.
+    space_amount : int
+        Amount of spaces per interval, by default 1.
 
     Return
     ------
@@ -81,7 +87,7 @@ def get_code_set(count, code_length, mode="ascii", space_interval=0):
     codes = set()
 
     while len(codes) < count:
-        code = get_code(code_length, mode, space_interval)
+        code = get_code(code_length, mode, space_interval, space_amount)
         codes.add(code)
 
     return codes
@@ -109,7 +115,7 @@ def get_code_length_needed(number_of_entries):
     return code_length
 
 
-def insert_spaces(code, interval):
+def insert_spaces(code, interval, space_amount=1):
     """Insert space after every x'th character, x = interval.
 
     Parameters
@@ -118,6 +124,8 @@ def insert_spaces(code, interval):
         String to add spaces to.
     interval : int
         Interval for inserting spaces.
+    space_amount : int
+        Amount of spaces per interval, by default 1.
 
     Returns
     -------
@@ -126,7 +134,7 @@ def insert_spaces(code, interval):
     """
     # Convert to list to insert spaces between characters
     code = list(code)
-    for i in range(interval - 1, len(code), interval):
-        code[i] += " "
+    for i in range(interval - 1, len(code) - interval, interval):
+        code[i] += " " * space_amount
 
     return "".join(code)
diff --git a/soitool/module_list.py b/soitool/module_list.py
index 9c4b9ba9795ce4dca060f7b839e5236cbb7b6a75..64c62e84200bf56fad6bb145357433b1bf463fff 100644
--- a/soitool/module_list.py
+++ b/soitool/module_list.py
@@ -171,10 +171,10 @@ class ModuleList(QListWidget):
 
             # Update module/attachment priority (order in list):
             if ModuleType(self.type) == ModuleType.MAIN_MODULE:
-                moving_module = self.parent.soi.modules.pop(origin)
+                moving_module = self.soi.modules.pop(origin)
                 self.soi.modules.insert(destination, moving_module)
             elif ModuleType(self.type) == ModuleType.ATTACHMENT_MODULE:
-                moving_module = self.parent.soi.attachments.pop(origin)
+                moving_module = self.soi.attachments.pop(origin)
                 self.soi.attachments.insert(destination, moving_module)
 
             self.soi.reorganize()
diff --git a/soitool/modules/code_table_base.py b/soitool/modules/code_table_base.py
index 7f3e2b9ec47cec3e23689b4d67a2f70847128a36..95ed2d1dc3c4cc832913422728e8e0b6c926870c 100644
--- a/soitool/modules/code_table_base.py
+++ b/soitool/modules/code_table_base.py
@@ -43,7 +43,7 @@ class CodeTableBase(ModuleBase, QTableWidget, metaclass=Meta):
         if size is None and data is None:
             self.generate_table()
             self.resizeColumnsToContents()
-            self.insert_headline()
+            self.insert_headline(self.headline)
 
             # Resize height of rows and set size of window
             resize_table(self, resize_column=False)
@@ -58,17 +58,23 @@ class CodeTableBase(ModuleBase, QTableWidget, metaclass=Meta):
                     self.setItem(i, j, item)
 
             self.resizeColumnsToContents()
+            self.insert_headline(data[0])
+
             resize_table(self, resize_column=False)
             self.setFixedWidth(size["width"])
             self.setFixedHeight(size["height"])
 
-            self.insert_headline(data[0])
+    def test(self):
+        """..."""
+        print("JADDA")
+        resize_table(self, resize_column=False)
 
     def generate_table(self):
         """Insert row identifiers and authentication codes..........."""
         # Set number of rows and columns
         self.setRowCount(self.start_no_of_codes)
         self.setColumnCount(3)
+        self.insert_row_identifiers()
 
         # Generate codes
         codes = list(
@@ -77,32 +83,26 @@ class CodeTableBase(ModuleBase, QTableWidget, metaclass=Meta):
                 self.code_length,
                 self.code_character_type,
                 self.space_interval,
+                self.space_amount,
             )
         )
-
-        # Insert table data
+        # Insert codes
         for i in range(self.start_no_of_codes):
-            if self.type == AUTHENTICATIONBOARDMODULE:
-                # Insert non-editable row identifier in first column
-                item_first = QTableWidgetItem(self.row_identifiers[i])
-                item_first.setFlags(item_first.flags() ^ Qt.ItemIsEditable)
-                self.setItem(i, 0, item_first)
-
-                # Insert non-editable row identifier (int) in second column
-                item_second = QTableWidgetItem(str(i))
-                item_second.setFlags(item_second.flags() ^ Qt.ItemIsEditable)
-                self.setItem(i, 1, item_second)
-
-                # Insert non-editable code in third column
-                item_third = QTableWidgetItem(codes[i])
-                item_third.setFlags(item_third.flags() ^ Qt.ItemIsEditable)
-                self.setItem(i, 2, item_third)
-            elif self.type == SUBTRACTORCODESMODULE:
-                print("NOPE")
-
-    def insert_headline(self):
-        """Insert headline text."""
-        item_headline = QTableWidgetItem(self.headline)
+            # Insert non-editable code in third column
+            item_third = QTableWidgetItem(codes[i])
+            item_third.setFlags(item_third.flags() ^ Qt.ItemIsEditable)
+            self.setItem(i, 2, item_third)
+
+    def insert_headline(self, text=None):
+        """Insert headline text.
+
+        Parameters
+        ----------
+        text : [type], optional
+            [description], by default None
+        """
+        headline = self.headline if text is not None else text
+        item_headline = QTableWidgetItem(headline)
         item_headline.setTextAlignment(Qt.AlignHCenter)
         item_headline.setFont(HEADLINE_FONT)
 
@@ -147,6 +147,21 @@ class CodeTableBase(ModuleBase, QTableWidget, metaclass=Meta):
 
         return codes
 
+    def keyPressEvent(self, event):
+        """Add or remove row when 'Ctrl + +' and 'Ctrl + -' are pressed."""
+        if (
+            event.modifiers() == Qt.ControlModifier
+            and event.key() == Qt.Key_Plus
+        ):
+            self.add_row()
+        elif (
+            event.modifiers() == Qt.ControlModifier
+            and event.key() == Qt.Key_Underscore
+        ):
+            self.remove_row()
+        else:
+            super().keyPressEvent(event)
+
     def get_size(self):
         """Return size of widget."""
         return get_table_size(self)
diff --git a/soitool/modules/module_authentication_board.py b/soitool/modules/module_authentication_board.py
index 6dc6912475e5c7a1315a0df3e904513b982fdf69..31329915f5c2689e72dc0abefb7e72f464c313e8 100644
--- a/soitool/modules/module_authentication_board.py
+++ b/soitool/modules/module_authentication_board.py
@@ -1,4 +1,4 @@
-"""Module containing SOI-module 'Autentifiseringstavle'."""
+"""Module containing SOI-module 'Autentiseringstavle'."""
 import string
 from PySide2.QtWidgets import QTableWidgetItem
 from PySide2 import QtGui
@@ -14,12 +14,13 @@ ROW_IDENTIFIERS = string.ascii_uppercase  # Characters for first column,
 # it's length determines maximum number of codes (rows).
 SPACE_INTERVAL = 5  # Adds space between sets of characters, 0 => no spaces
 # If code is 123456 and interval is 2, code will be 12 34 56
+SPACE_AMOUNT = 2
 
 HEADLINE_TEXT = "Autentiseringstavle"
 
 
 class AuthenticationBoardModule(CodeTableBase):
-    """Modified QTableWidget representing a 'Autentifiseringstavle'.
+    """Modified QTableWidget representing a 'Autentiseringstavle'.
 
     By default, the widget initializes with a headline, a row-count of
     START_NO_OF_AUTHENTICATION_CODES and three columns.
@@ -42,11 +43,6 @@ class AuthenticationBoardModule(CodeTableBase):
     def __init__(self, size=None, data=None):
         self.type = "AuthenticationBoardModule"
 
-        self.start_no_of_codes = START_NO_OF_CODES
-        self.code_length = CODE_LENGTH
-        self.space_interval = SPACE_INTERVAL
-        self.row_identifiers = ROW_IDENTIFIERS
-
         if CODE_CHARACTER_TYPE == "ascii":
             self.code_characters = string.ascii_uppercase
         elif CODE_CHARACTER_TYPE == "digits":
@@ -58,25 +54,31 @@ class AuthenticationBoardModule(CodeTableBase):
                 "Invalid value for CONSTANT 'CODE_CHARACTER_TYPE': "
                 "'{}'".format(CODE_CHARACTER_TYPE)
             )
+        self.start_no_of_codes = START_NO_OF_CODES
+        self.code_length = CODE_LENGTH
+        self.space_interval = SPACE_INTERVAL
+        self.space_amount = SPACE_AMOUNT
         self.code_character_type = CODE_CHARACTER_TYPE
         self.headline = HEADLINE_TEXT
 
         CodeTableBase.__init__(self, size, data)
-
-    def keyPressEvent(self, event):
-        """Add or remove row when 'Ctrl + +' and 'Ctrl + -' are pressed."""
-        if (
-            event.modifiers() == Qt.ControlModifier
-            and event.key() == Qt.Key_Plus
-        ):
-            self.add_row()
-        elif (
-            event.modifiers() == Qt.ControlModifier
-            and event.key() == Qt.Key_Underscore
-        ):
-            self.remove_row()
-        else:
-            super(AuthenticationBoardModule, self).keyPressEvent(event)
+        # If headline changes
+        self.cellChanged.connect(
+            lambda: resize_table(self, resize_column=False)
+        )
+
+    def insert_row_identifiers(self):
+        """Insert values in column one and two."""
+        for i in range(self.rowCount()):
+            # Insert non-editable row identifier in first column
+            item_first = QTableWidgetItem(ROW_IDENTIFIERS[i])
+            item_first.setFlags(item_first.flags() ^ Qt.ItemIsEditable)
+            self.setItem(i, 0, item_first)
+
+            # Insert non-editable row identifier (int) in second column
+            item_second = QTableWidgetItem(str(i))
+            item_second.setFlags(item_second.flags() ^ Qt.ItemIsEditable)
+            self.setItem(i, 1, item_second)
 
     def add_row(self):
         """Insert row below the selected row and add data."""
diff --git a/soitool/modules/module_base.py b/soitool/modules/module_base.py
index c608a17177d43a16371b675d8f5a815f82a87e27..8300256e464779c4449045742238c636ea8d5488 100644
--- a/soitool/modules/module_base.py
+++ b/soitool/modules/module_base.py
@@ -54,8 +54,20 @@ def resize_table(widget, resize_row=True, resize_column=True):
     if resize_column:
         widget.resizeColumnsToContents()
 
+    widget.resizeColumnToContents(2)
     width, height = get_table_size(widget)
 
+    headline = widget.item(0, 0).text()
+    fm = QtGui.QFontMetrics(HEADLINE_FONT)
+    headline_width = fm.width(headline) + 10  # + 10 offset
+
+    # If headline is wider than widget
+    if width < headline_width:
+        difference = headline_width - width
+        width += difference
+        old_width = widget.columnWidth(2)
+        widget.setColumnWidth(2, old_width + difference)
+
     widget.setFixedWidth(width)
     widget.setFixedHeight(height)
 
diff --git a/soitool/modules/module_subtractorcodes.py b/soitool/modules/module_subtractorcodes.py
index 3233b65ed8a476c624a638b7392bdf4931e972f6..c048c8ebdcb7f11678bae129ca91f83ff8f18493 100644
--- a/soitool/modules/module_subtractorcodes.py
+++ b/soitool/modules/module_subtractorcodes.py
@@ -6,9 +6,11 @@ from PySide2.QtCore import Qt
 from soitool.modules.module_base import resize_table
 from soitool.modules.code_table_base import CodeTableBase
 
-START_NO_OF_CODES = 7
+START_NO_OF_CODES = 7  # Maximum value is len(ALPHABET)/2 columns = 13
 CODE_LENGTH = 8
 SPACE_INTERVAL = 4
+SPACE_AMOUNT = 2
+ALPHABET = string.ascii_uppercase  # Characters for first and second column
 
 HEADLINE_TEXT = "Subtraktorkoder"
 
@@ -19,21 +21,95 @@ class SubtractorcodesModule(CodeTableBase):
     def __init__(self, size=None, data=None):
         self.type = "SubtractorcodesModule"
 
+        if START_NO_OF_CODES > 13:
+            raise ValueError(
+                "Invalid value for CONSTANT 'START_NO_OF_CODES': "
+                "'{}'".format(START_NO_OF_CODES)
+            )
+
         self.start_no_of_codes = START_NO_OF_CODES
         self.code_length = CODE_LENGTH
         self.space_interval = SPACE_INTERVAL
-        # Characters for first and second column,
-        # it's length/2 it the maximum number of codes (rows).
-        self.row_identifiers = string.ascii_uppercase
+        self.space_amount = SPACE_AMOUNT
         self.code_character_type = "digits"
         self.headline = HEADLINE_TEXT
 
         CodeTableBase.__init__(self, size, data)
+        # If headline changes
+        self.cellChanged.connect(
+            lambda: resize_table(self, resize_column=False)
+        )
+
+    def insert_row_identifiers(self):
+        """Insert table data.
+
+        Parameters
+        ----------
+        data : List
+            List of codes to insert.
+        """
+        split_one = ALPHABET[0 : self.rowCount()]
+        split_two = ALPHABET[self.rowCount() : self.rowCount() * 2]
+
+        for i in range(2):
+            for j in range(self.rowCount()):
+                text = split_one[j] if i == 0 else split_two[j]
+                item = QTableWidgetItem(text)
+                item.setFlags(item.flags() ^ Qt.ItemIsEditable)
+                self.setItem(j, i, item)
+
+    def add_row(self):
+        """..."""
+        row_index = self.currentRow()
+        # If maximum amount of rows not reached and a row is selected
+        # (+ 1 to skip row containing headline)
+        if self.rowCount() < len(ALPHABET) / 2 + 1 and row_index != -1:
+            # Generate unique code and insert row
+            code = self.generate_unique_authentication_code()
+            self.insertRow(row_index + 1)
+
+            # Insert values in first and second column
+            split_one = ALPHABET[0 : self.rowCount() - 1]
+            split_two = ALPHABET[self.rowCount() - 1 : self.rowCount() * 2 - 2]
+
+            for i in range(2):
+                for j in range(1, self.rowCount()):  # From 1 to skip headline
+                    text = split_one[j - 1] if i == 0 else split_two[j - 1]
+                    item = QTableWidgetItem(text)
+                    item.setFlags(item.flags() ^ Qt.ItemIsEditable)
+                    self.setItem(j, i, item)
+
+            # Insert code in third column
+            item_third = QTableWidgetItem(code)
+            item_third.setFlags(item_third.flags() ^ Qt.ItemIsEditable)
+            self.setItem(row_index + 1, 2, item_third)
+
+            # Resize code-column in case it got wider
+            # Example: 'BGD' is wider than 'III' (depending on font)
+            self.resizeColumnToContents(2)
+            resize_table(self, resize_column=False)
+
+    def remove_row(self):
+        """Remove selected row."""
+        row_index = self.currentRow()
+        # If at least one row (+ headline-row) exists and a row other than
+        # headline-row is selected
+        if self.rowCount() > 2 and row_index != 0 and row_index != -1:
+            # Remove row
+            self.removeRow(row_index)
+
+        split_one = ALPHABET[0 : self.rowCount() - 1]
+        split_two = ALPHABET[self.rowCount() - 1 : self.rowCount() * 2 - 2]
+        for i in range(2):
+            for j in range(1, self.rowCount()):  # From 1 to skip headline
+                # Insert values in first and second column
+                text = split_one[j - 1] if i == 0 else split_two[j - 1]
+                self.item(j, i).setText(text)
 
     @staticmethod
     def get_user_friendly_name():
         """Get user-friendly name of module."""
-        return "Autentiseringstavle"
+        return "Subtraktorkoder"
 
     @staticmethod
     def get_icon():
diff --git a/soitool/serialize_export_import_soi.py b/soitool/serialize_export_import_soi.py
index d7856c1e2f6bd48e840f3486f093918864075abd..081e4f4b80a82f331d240353869c08b10dfc6b25 100644
--- a/soitool/serialize_export_import_soi.py
+++ b/soitool/serialize_export_import_soi.py
@@ -8,6 +8,7 @@ from soitool.modules.module_table import TableModule
 from soitool.modules.module_authentication_board import (
     AuthenticationBoardModule,
 )
+from soitool.modules.module_subtractorcodes import SubtractorcodesModule
 from soitool.modules.module_freetext import FreeTextModule
 
 # Valid schema for serialized SOI
@@ -231,6 +232,15 @@ def import_soi(file_path):
                     "meta": module["meta"],
                 }
             )
+        elif module_type == "SubtractorcodesModule":
+            size = module["size"]
+            data = module["data"]
+            modules.append(
+                {
+                    "widget": SubtractorcodesModule(size, data),
+                    "meta": module["meta"],
+                }
+            )
         elif module_type == "FreeTextModule":
             size = module["size"]
             data = module["data"]