Exporteer elke tabel als CSV en voer vervolgens een Finder-opdracht uit die die positie uitleest en een overzicht maakt, om dezelfde cel uit herhaalde voorraadtabellen te verzamelen. In deze handleiding wordt B3 verzameld, blijft de bestandsnaam van elke bron behouden en wordt overschrijven van een bestaand resultaat voorkomen.

Kies de juiste invoer voordat je de opdracht maakt

Deze workflow is bedoeld voor iemand die meerdere voorraadtabellen met dezelfde indeling beheert en één rij per tabel in een apart overzicht wil. Het voorbeeld gebruikt drie wegwerpbestanden met synthetische aantallen. Elk bestand bevat één geëxporteerde tabel; het doel is kolom B, rij 3, inclusief de kopregel.

Houd drie zaken uit elkaar: het spreadsheetdocument, de tabel daarin en het geëxporteerde CSV-bestand. In de documentatie van Numbers staat dat je tabellen als afzonderlijke bestanden of samengevoegd kunt exporteren naar CSV. Kies voor deze taak afzonderlijke bestanden: door tabellen samen te voegen kan de positie van de gewenste record veranderen. CSV-exportbestanden bevatten celwaarden, dus het resulterende overzicht is een momentopname. Exporteer naar andere bestandsstructuren in Numbers op de Mac.

De onderstaande opdracht laat een klein Python-programma de gegevens uitlezen. Het behandelt een Numbers-document of Excel-werkmap niet als platte tekst en gaat er niet van uit dat een actie toegang heeft tot cellen zodra je een spreadsheetbestand accepteert als invoer. Apple beschrijft hoe je via het infovenster kunt zien welke invoer een actie accepteert en welke uitvoer deze oplevert. Gebruik dat venster om de acties te controleren die op je Mac beschikbaar zijn. Navigeer door de actielijst in Opdrachten op de Mac.

Gebruik deze beslistabel voordat je begint:

Uitgangssituatie Voorbereiding voor deze workflow
Eén overeenkomende tabel in elk Numbers-document Exporteer elke tabel als CSV.
Meerdere overeenkomende tabellen in één document Exporteer afzonderlijke CSV-bestanden en bepaal welke tabellen je nodig hebt.
Bestaande CSV-bestanden met komma’s als scheidingsteken Controleer de codering, indeling en doelpositie.
Verschillende indelingen of verschuivende voorraadregels Standaardiseer eerst de wegwerpvoorbeelden; met alleen een vaste coördinaat kun je de gewenste hoeveelheid niet identificeren.

Voor het voorbeeld moet in elke bron Counted units staan in A3 en de gewenste waarde in B3. Controle van het aangrenzende label is een nuttige extra controle: bij een verschoven rij stopt de uitvoering in plaats van stilzwijgend een niet-gerelateerde waarde te verzamelen. Niet elke mogelijke indelingsfout is hiermee te detecteren, dus controleer beide cellen bij het voorbereiden van de invoer.

Maak wegwerpbestanden voor de voorraad

Voor dit voorbeeld moet Python 3 afzonderlijk zijn geïnstalleerd. Bij gebruik van het standaardinstallatieprogramma van de Python-website worden uitvoerbare koppelingen geplaatst in /usr/local/bin/. De onderstaande opdrachten gebruiken expliciet /usr/local/bin/python3, zodat ze niet afhankelijk zijn van het zoekpad voor opdrachten van de opdracht. Volg de installatie-instructies voor de ondersteunde Python-versie en controleer daarna of deze opdracht werkt. Python gebruiken op macOS.

/usr/local/bin/python3 --version

Ontbreekt dit pad, voltooi dan eerst de Python-installatie. Het programma gebruikt alleen de standaardbibliotheek van Python; er zijn geen extra pakketten nodig. In de Terminal-handleiding van Apple wordt uitgelegd dat je opdrachten kunt uitvoeren met het volledige pad naar het uitvoerbare bestand, gevolgd door de argumenten. Voer opdrachten uit en gebruik tools in Terminal op de Mac.

Plak deze volledige opdracht in Terminal om de synthetische invoer te maken. De opdracht maakt Inventory Demo aan op je bureaublad en stopt als die map al bestaat. Gebruik een nieuwe wegwerpmap in plaats van deze voorbeelden samen te voegen met een bestaande map.

/usr/local/bin/python3 - <<'PY'
import csv
from pathlib import Path

root = Path.home() / "Desktop" / "Inventory Demo"
root.mkdir()
examples = [
    ("Birch", "A", "12"),
    ("Cedar", "B", "7"),
    ("Maple", "C", "0"),
]
for name, bin_name, count in examples:
    with (root / f"{name}.csv").open(
        "x", encoding="utf-8", newline=""
    ) as handle:
        csv.writer(handle).writerows([
            ["Item", "Value"],
            ["Bin", bin_name],
            ["Counted units", count],
        ])
print(root)
PY

Open voor een afzonderlijke test van de exportstap in Numbers één wegwerp-CSV-bestand in Numbers en exporteer het naar een andere wegwerpmap met Archief > Exporteer naar > CSV. Kies één bestand per tabel, laat Inclusief tabelnamen uitgeschakeld en gebruik UTF-8-codering. Controleer de geëxporteerde tabel om te bevestigen dat A3 en B3 nog steeds het bedoelde label en de bedoelde waarde bevatten. Apple documenteert deze exportopties. Exportinstellingen voor Numbers.

Hernoem de extensie van een spreadsheet niet naar .csv als vervanging voor exporteren. Dit programma verwacht echte tekst met komma’s als scheidingstekens. Laat de drie oorspronkelijke synthetische CSV-bestanden bij elkaar staan voor de volgende stappen in deze handleiding.

Maak het programma dat het overzicht samenstelt

Sla het volgende volledige programma met een teksteditor op als overview.py in Inventory Demo. Controleer of de bestandsnaam eindigt op .py en niet op .py.txt. Het programma accepteert bestandspaden als argumenten, leest B3 en maakt overview.csv in de gedeelde map.

import csv
import io
import sys
from pathlib import Path

ROW, COLUMN = 2, 1  # Zero-based: B3
LABEL = "Counted units"

def build_overview(arguments):
    if not arguments:
        raise ValueError("Select at least one source CSV.")
    paths = [Path(name).expanduser().resolve(strict=True)
             for name in arguments]
    if len(set(paths)) != len(paths):
        raise ValueError("The same source was supplied twice.")
    if len({path.parent for path in paths}) != 1:
        raise ValueError("Keep all source CSVs in one folder.")
    rows = []
    for path in sorted(paths, key=lambda p: p.name):
        if (not path.is_file() or path.suffix.lower() != ".csv"
                or path.name.casefold() == "overview.csv"):
            raise ValueError(f"Not a source CSV: {path.name}")
        with path.open(encoding="utf-8-sig", newline="") as handle:
            records = list(csv.reader(handle, strict=True))
        if len(records) <= ROW or len(records[ROW]) <= COLUMN:
            raise ValueError(f"{path.name}: B3 does not exist.")
        if records[ROW][0] != LABEL:
            raise ValueError(f"{path.name}: A3 must be {LABEL!r}.")
        value = records[ROW][COLUMN]
        status = "blank" if value.strip() == "" else "present"
        rows.append([path.name, "B3", value, status])
    buffer = io.StringIO(newline="")
    writer = csv.writer(buffer)
    writer.writerow(["Source file", "Cell", "Value", "Status"])
    writer.writerows(rows)
    return paths[0].parent / "overview.csv", buffer.getvalue()

def main(arguments):
    try:
        destination, content = build_overview(arguments)
        with destination.open("x", encoding="utf-8", newline="") as handle:
            handle.write(content)
    except (OSError, ValueError, csv.Error) as error:
        print(f"Stopped: {error}", file=sys.stderr)
        return 1
    print(f"Created: {destination}")
    return 0

if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))

Het programma gebruikt een CSV-parser in plaats van tekst op komma’s of regeleinden te splitsen. De reader van Python retourneert velden als strings en de documentatie schrijft voor CSV-bestanden te openen met newline="". Zo worden ook velden met aanhalingstekens verwerkt die komma’s of regeleinden bevatten. Het programma behoudt de uitgelezen waarde zonder die op te tellen of om te zetten naar een getal. CSV-bestanden lezen en schrijven.

Enkele bewuste beperkingen maken het resultaat makkelijker te controleren. Elk invoerbestand moet bestaan, alle opgeloste bronpaden moeten naar dezelfde map verwijzen en dubbele opgeloste paden worden afgewezen. Het programma sorteert op bestandsnaam in plaats van uit te gaan van de selecteervolgorde in Finder. Ook wordt invoer met de naam overview.csv afgewezen, om te voorkomen dat het vorige resultaat per ongeluk wordt meegenomen.

Alle bronnen worden gelezen en gecontroleerd voordat het maken van de uitvoer begint. Een ontbrekende B3 of een onverwacht label in A3 stopt de uitvoering. Een bestaande maar lege B3 levert een rij op met de markering blank; een waarde van 0 blijft 0 en krijgt de markering present. Zo hebben een ontbrekende cel, een lege cel en een nultelling verschillende uitkomsten.

De uitvoer wordt gemaakt met de exclusieve modus "x". Volgens de documentatie van Python mislukt deze modus wanneer de bestemming al bestaat. Het programma vervangt dus noch het vorige overzicht, noch maakt het een bestandsnaam met een volgnummer. Bij een fout tijdens het schrijven kan er nog steeds een onvolledig nieuw bestand achterblijven; controleer elk bestand dat na een schrijffout achterblijft voordat je het opnieuw probeert. Bestandsopeningsmodi van Python.

Koppel het programma aan een Finder-opdracht

Maak in Opdrachten een opdracht met de naam Inventory Overview. Open Details, schakel Gebruik als snelle taak in en selecteer Finder. Laat in de invoerconfiguratie Bestanden ingeschakeld en schakel niet-gerelateerde inhoudstypen uit. Apple documenteert dat Finder beschikbaar is voor opdrachten die bestanden of mappen accepteren, evenals de opties om de geaccepteerde invoer te beperken. Voer een opdracht uit terwijl je op de Mac werkt, Beperk de invoer voor een opdracht.

Stel het gedrag bij invoer zonder gegevens in op Stop en antwoord, met een bericht zoals Selecteer de CSV-bronbestanden in Finder. Zo wordt voorkomen dat een lege selectie tot een onduidelijke uitvoering leidt. De optie en het antwoordveld worden beschreven in de invoerconfiguratiehandleiding van Apple. Kies de reactie op ontbrekende invoer.

Voeg Voer shellscript uit toe. Stel Shell in op /bin/zsh, verbind de Invoer met Invoer opdracht en stel Geef invoer door in op als argumenten. Vervang het voorbeeldscript door deze volledige opdracht:

/usr/local/bin/python3 "$HOME/Desktop/Inventory Demo/overview.py" "$@"

Laat de aanhalingstekens staan. De geciteerde "$@" geeft de binnenkomende argumenten afzonderlijk door, zodat bestandsnamen met spaties behouden blijven. Om dezelfde reden staat ook het pad naar het script tussen aanhalingstekens. In de zsh-handleiding worden positionele parameters en afzonderlijke uitbreiding van geciteerde array-elementen beschreven; in de Terminal-handleiding van Apple wordt ook het citeren van paden uitgelegd. Parameters, Geef bestanden en mappen op in Terminal.

Als Opdrachten vereist dat scripts zijn ingeschakeld, kies je Opdrachten > Instellingen > Geavanceerd en selecteer je Uitvoeren van scripts toestaan. Apple beschrijft deze instelling onder het toestaan van scripts vanuit een opdracht. Geavanceerde instellingen voor Opdrachten.

De ingestelde workflow verloopt als volgt: de geselecteerde bestandsobjecten gaan de opdracht in, hun paden worden shellargumenten en Python leest die bestanden en schrijft het overzicht. Het geslaagde tekstuele resultaat van de shellactie is een bericht Created: met het pad naar de bestemming. Dat bericht is niet het CSV-bestand zelf. Er is geen volgende bewaaractie nodig, omdat het programma het bestand al heeft gemaakt.

Selecteer in Finder alleen Birch.csv, Cedar.csv en Maple.csv. Klik met de Control-toets ingedrukt op de selectie en kies Snelle taken > Inventory Overview. Ontbreekt de opdracht, gebruik dan Meer > Pas aan om de ingeschakelde Finder-extensies te bekijken en controleer vervolgens opnieuw de geaccepteerde invoertypen. Apple documenteert zowel het aanpassen van Snelle taken in Finder als het toevoegen van opdrachten aan dat menu. Voer Snelle taken uit in Finder op de Mac.

Controleer het resultaat en behandel herhaalde uitvoeringen

Open overview.csv in de demomap met Numbers. Met de meegeleverde synthetische bestanden moet de inhoud er als volgt uitzien:

Source file,Cell,Value,Status
Birch.csv,B3,12,present
Cedar.csv,B3,7,present
Maple.csv,B3,0,present

Controleer of er voor elke geselecteerde bron één uitvoerrij is en of de bestandsnamen naar de bedoelde tabellen verwijzen. De waarden in het voorbeeld dienen ter illustratie; het zijn geen gemeten voorraadresultaten. Het programma vermeldt of een waarde aanwezig is, maar controleert niet of die waarde een geldige telling is.

Volg deze diagnosevolgorde als iets afwijkt:

  1. Geen opdracht in Finder: controleer de instelling Finder, de geaccepteerde invoer Bestanden en de ingeschakelde extensie.
  2. Uitvoerbaar bestand of script ontbreekt: controleer het Python-pad en of overview.py in de opgegeven demomap staat.
  3. B3 ontbreekt of A3 is onjuist: inspecteer de geëxporteerde records en exportopties van de bron voordat je het programma wijzigt.
  4. Een onverwachte lege waarde: inspecteer B3; het programma laat lege waarden opzettelijk leeg.
  5. De bestemming bestaat al: hernoem het vorige wegwerpoverzicht of verplaats het buiten de bronmap voordat je het opnieuw uitvoert.

Je kunt dezelfde opdracht ook vanuit Terminal uitvoeren om de invoerroute te controleren. Apple documenteert -i voor het doorgeven van bestandsinvoer; als je een pad via een pipe doorgeeft, wordt het als tekst doorgegeven. Gebruik de expliciete bestanden hieronder, zonder uitvoervlag, omdat het Python-programma verantwoordelijk is voor het maken van de uitvoer. Dezelfde regel voor botsende namen is van toepassing. Voer opdrachten uit vanaf de commandoregel.

shortcuts run "Inventory Overview" -i \
  "$HOME/Desktop/Inventory Demo/Birch.csv" \
  "$HOME/Desktop/Inventory Demo/Cedar.csv" \
  "$HOME/Desktop/Inventory Demo/Maple.csv"

Elk nieuw overzicht vertegenwoordigt de CSV-bestanden die voor die uitvoering zijn geselecteerd. Als je een spreadsheet wijzigt, moet je die opnieuw exporteren en de opdracht opnieuw uitvoeren. Doordat de bronbestandsnaam behouden blijft, het aangrenzende label wordt gecontroleerd en lege waarden van nul worden onderscheiden, kun je dit kleine overzicht makkelijker controleren voordat je het gebruikt bij je volgende voorraadcontrole.

Bronnen