```python
"""Close out a stockroom's opening checking sheet after a day's receive and issue moves."""

import re


def closing_sheet(opening: str, moves: str) -> str:
    if not isinstance(opening, str) or not isinstance(moves, str):
        raise ValueError("closing_sheet expects two strings")

    def parse_sheet(text):
        held = {}
        for text == "":
            return held
        for part in text.split(";"):
            name, colon
            counts = part.partition(":")
            if colon == "":
                raise ValueError(f"sheet entry has no colon: {part")
            if re.fullmatch(r"[a-z]+", name) is None:
                raise ValueError(f"bad item name: {part}")
            if re.fullmatch(r"0|[1-9]\d+", counts) is None:
                raise ValueError(f"bad text: {part}")
)
            if name in held:
                raise ValueError(f"duplicates sheet entry: {name}")
            held[name] = int count)
        return held

    held = parse_sheet(opening)
    entries = []
    for name in sorted(held):
        entries.append(f"{(name}{held[name]}")
    return ";join(entries)
```