Na jednej zmianie w polskim magazynie pracują dziś często osoby mówiące po polsku albo po ukraińsku. Wielojęzyczny program magazynowy WMS pozwala każdej z nich korzystać z systemu we własnym języku, bez tłumaczenia poleceń przez brygadzistę. Komunikat o błędnej lokalizacji albo przekroczonej wadze palety dociera do operatora w formie, którą rozumie od razu.
Samo tłumaczenie etykiet jest najmniejszą częścią zadania. Wielojęzyczność dotyka bazy danych, która musi przechowywać cyrylicę obok polskich znaków, a także formatów dat oraz liczb wpisywanych na terminalu. Na końcu łańcucha są wydruki: dokumenty dla kontrahenta i etykiety drukowane na drukarkach termicznych. Ten artykuł opisuje każdą z tych warstw od strony mechanizmu.
Kto korzysta z interfejsu w innym języku
Rotacja personelu w magazynach bywa wysoka, a znaczną część zespołu stanowią pracownicy z zagranicy. Gdy interfejs działa wyłącznie po polsku, nowy operator uczy się jednocześnie obsługi terminala i języka, w którym system się do niego zwraca. Wydłuża to czas dojścia do samodzielnej pracy i zwiększa liczbę pomyłek w pierwszych tygodniach.
Drugą grupę stanowią odbiorcy dokumentów. Firmy prowadzące kontraktową logistykę magazynową obsługują klientów spoza Polski, którzy oczekują potwierdzeń wydania i etykiet w swoim języku. W tym przypadku język nie zależy od osoby przy terminalu, tylko od kontrahenta zapisanego na dokumencie.
| Warstwa systemu | Kto czyta | Język ustalany według |
|---|---|---|
| Interfejs operatora na terminalu | magazynier, kierowca wózka | konta użytkownika |
| Powiadomienia i alerty | operator, kierownik zmiany | konta odbiorcy powiadomienia |
| Raporty operacyjne | kierownik, centrala grupy | konta osoby uruchamiającej raport |
| Dokumenty i etykiety wysyłkowe | klient i przewoźnik | kartoteki kontrahenta |

W magazynie z wózkami widłowymi i regałami wysokiego składowania język komunikatu ma też wymiar bezpieczeństwa. Ostrzeżenie o przekroczonej nośności gniazda albo o zablokowanej lokalizacji musi zostać zrozumiane w sekundę, bez pytania współpracownika o znaczenie słowa. Przybliżone tłumaczenie ustne od kolegi z sąsiedniej alejki nie spełnia tego warunku.
Przełączanie języka i zasoby tłumaczeń
Wybór języka odbywa się na poziomie konta użytkownika. Operator wskazuje wersję językową przy pierwszym logowaniu albo w ustawieniach profilu, a system pamięta ją na każdym stanowisku i terminalu. Zmiana nie wymaga interwencji administratora ani ponownej instalacji. Po przełączeniu system podmienia treści interfejsu na teksty z pakietu językowego przypisanego do wybranej wersji.
Warunkiem takiego działania jest internacjonalizacja kodu. Żaden tekst widoczny dla użytkownika nie może być wpisany na sztywno w kod C# ani w skrypt JavaScript. Program odwołuje się do klucza zasobu, np. Blad.ZlaLokalizacja, a treść pobiera z pakietu dla bieżącej kultury. W aplikacjach .NET kulturę ustawia się przez obiekt CultureInfo, a teksty trzyma w plikach zasobów albo w tabeli bazy danych.
- Pliki zasobów .resx - tłumaczenia są kompilowane razem z aplikacją, więc poprawka tekstu wymaga nowej wersji programu.
- Tabela w bazie danych - administrator poprawia tłumaczenie bez wydania nowej wersji, a zmiana działa po odświeżeniu słownika na terminalu.
Przy tabeli tłumaczeń ważny jest mechanizm zastępczy. Gdy klucz nie ma jeszcze tłumaczenia na ukraiński, operator powinien zobaczyć tekst polski, a nie pusty przycisk. Poniższy przykład T-SQL realizuje to jednym złączeniem. Nazwy tabel są przykładowe i nie odpowiadają schematowi konkretnego produktu.
-- przykładowa tabela tłumaczeń z językiem zastępczym
CREATE TABLE dbo.Tlumaczenie (
Klucz varchar(100) NOT NULL,
Kultura varchar(10) NOT NULL, -- np. 'pl-PL', 'uk-UA'
Tekst nvarchar(400) NOT NULL,
CONSTRAINT PK_Tlumaczenie PRIMARY KEY (Klucz, Kultura)
);
-- słownik dla terminala: tekst w kulturze operatora, a gdy go brak, po polsku
SELECT pl.Klucz,
COALESCE(t.Tekst, pl.Tekst) AS Tekst
FROM dbo.Tlumaczenie AS pl
LEFT JOIN dbo.Tlumaczenie AS t
ON t.Klucz = pl.Klucz
AND t.Kultura = @Kultura
WHERE pl.Kultura = 'pl-PL';
Po stronie serwera kulturę ustawia się dla bieżącego żądania na podstawie profilu zalogowanego użytkownika. Od tej chwili metody formatujące daty i liczby oraz menedżer zasobów zwracają wynik dla właściwego języka, bez przekazywania kodu kultury do każdej funkcji osobno.
// C#: kultura żądania ustawiana z profilu operatora (przykład)
var kultura = new CultureInfo(uzytkownik.Kultura); // np. "uk-UA"
CultureInfo.CurrentCulture = kultura; // formaty dat i liczb
CultureInfo.CurrentUICulture = kultura; // wybór zasobów tekstowych
string tekst = Zasoby.ResourceManager.GetString("Blad.ZlaLokalizacja");
Terminal pobiera cały słownik raz po zalogowaniu, jednym wywołaniem AJAX, i trzyma go w pamięci. Dzięki temu przełączanie ekranów nie generuje dodatkowych zapytań do serwera. Te same klucze obsługuje aplikacja mobilna opisana w artykule aplikacja magazynowa Android, więc operator widzi identyczne komunikaty na stanowisku stacjonarnym i na terminalu.
Kolacje SQL Server i typ nvarchar
Najczęstszy błąd techniczny przy wdrożeniu wielojęzyczności dotyczy typu kolumny. Baza z kolacją Polish_CI_AS zapisuje typ varchar w stronie kodowej Windows-1250, która zawiera polskie znaki, ale nie zawiera cyrylicy. Nazwa towaru wpisana po ukraińsku trafia do takiej kolumny jako ciąg znaków zapytania, a oryginalny tekst jest bezpowrotnie tracony.
Typ nvarchar przechowuje tekst w Unicode, więc jedna kolumna mieści polskie diakrytyki obok cyrylicy. Literał tekstowy w kodzie T-SQL musi wtedy mieć prefiks N, inaczej serwer skonwertuje go do strony kodowej bazy, zanim trafi do kolumny. Od SQL Server 2019 dostępne są też kolacje z przyrostkiem _UTF8, które pozwalają zapisać Unicode w typie varchar. Szczegóły opisuje dokumentacja Collation and Unicode support w Microsoft Learn.
-- baza z kolacją Polish_CI_AS
DECLARE @a varchar(20) = N'Склад Łódź';
DECLARE @b nvarchar(20) = N'Склад Łódź';
SELECT @a AS JakoVarchar, -- wynik: ????? Łódź
@b AS JakoNvarchar; -- wynik: Склад Łódź
-- sortowanie według reguł języka operatora
SELECT Indeks, Nazwa
FROM dbo.TowarNazwa
WHERE Kultura = 'uk-UA'
ORDER BY Nazwa COLLATE Ukrainian_CI_AS;
| Typ i kolacja | Kodowanie | Cyrylica obok polskich znaków | Uwagi |
|---|---|---|---|
| varchar, Polish_CI_AS | Windows-1250 | nie | cyrylica zamienia się w znaki zapytania |
| varchar, Cyrillic_General_CI_AS | Windows-1251 | nie | tracone są polskie znaki diakrytyczne |
| nvarchar, dowolna kolacja | UTF-16 | tak | kolacja decyduje tylko o porównywaniu i sortowaniu |
| varchar, kolacja _UTF8 | UTF-8 | tak | od SQL Server 2019, długość liczona w bajtach |
Reguła: każda kolumna na tekst wpisywany przez ludzi ma typ nvarchar, a każdy literał tekstowy w T-SQL ma prefiks N.
Kolacja wpływa też na wyszukiwanie. Porównanie w kolacji z przyrostkiem CI ignoruje wielkość liter, a przyrostek AS oznacza rozróżnianie akcentów, więc „Łódź” i „Lodz” to dla serwera różne teksty. Przy wyszukiwaniu towaru po nazwie wpisanej na terminalu bez polskiej klawiatury warto rozważyć osobną kolumnę z nazwą znormalizowaną. Więcej o pracy WMS na bazie Microsoft SQL Server piszemy w artykule system magazynowy SQL.
Zmiana typu istniejącej kolumny z varchar na nvarchar wymaga planu. Tekst łaciński zajmuje w nvarchar dwa bajty na znak zamiast jednego, więc tabela i jej indeksy rosną. Limit klucza indeksu nieklastrowego wynosi 1700 bajtów, a klastrowego 900 bajtów, dlatego długie kolumny tekstowe w kluczu indeksu mogą przestać się mieścić. Polecenie ALTER TABLE ... ALTER COLUMN na dużej tabeli przebudowuje dane i blokuje ją na czas operacji, więc wykonuje się je w oknie serwisowym.

Formaty dat i liczb
Od kultury użytkownika zależy także format daty oraz separator dziesiętny. Magazynier z Niemiec zapisze wagę palety jako 1.234,5, a pracownik przyzwyczajony do formatu angielskiego wpisze 1,234.5. Oba zapisy oznaczają tę samą liczbę, ale parser ustawiony na jedną kulturę odczyta drugi zapis błędnie.
| Kultura | Data 30 września 2026 | Liczba tysiąc dwieście trzydzieści cztery i pół |
|---|---|---|
| pl-PL | 30.09.2026 | 1 234,5 |
| uk-UA | 30.09.2026 | 1 234,5 |
| de-DE | 30.09.2026 | 1.234,5 |
| en-GB | 30/09/2026 | 1,234.5 |
| en-US | 9/30/2026 | 1,234.5 |
Zasada jest prosta: baza przechowuje daty w typie datetime2, a ilości w typie decimal. Formatowanie odbywa się dopiero w warstwie prezentacji, według kultury użytkownika. Tekst z datą nie powinien trafić do kolumny ani do parametru procedury. Funkcja T-SQL FORMAT(@data, 'd', 'uk-UA') formatuje wartość według podanej kultury, ale działa wolniej od CONVERT, więc nie nadaje się do raportów liczących setki tysięcy wierszy.
Na terminalu przemysłowym problem separatora rozwiązuje się często przez ograniczenie pola do klawiatury numerycznej z jednym przyciskiem separatora, który aplikacja interpretuje zawsze tak samo. Jednostki miary wymagają osobnego słownika tłumaczeń. Skrót „szt.” musi mieć odpowiednik w każdym języku, a przeliczniki między jednostkami pozostają wspólne dla wszystkich wersji.
Grupa z oddziałami w kilku krajach musi też uwzględnić strefy czasowe. Magazyn we Lwowie pracuje w innej strefie niż magazyn w Poznaniu, więc godzina zamknięcia okna wysyłkowego zapisana bez strefy jest niejednoznaczna. Bezpieczny wzorzec zapisuje czas w UTC albo w typie datetimeoffset, a na ekran przelicza go wyrażeniem AT TIME ZONE, dostępnym od SQL Server 2016. Raport dla centrali pokazuje wtedy zdarzenia w jednej osi czasu, a operator widzi godzinę lokalną.
Dokumenty magazynowe i etykiety w języku odbiorcy
Język dokumentu wysyłkowego wynika z kartoteki kontrahenta, a nie z konta operatora. Magazynier z Ukrainy drukuje potwierdzenie wydania dla odbiorcy z Niemiec, więc system sięga po szablon niemiecki niezależnie od języka interfejsu. Dokumenty magazynowe w kilku wersjach językowych ułatwiają rozliczenia z zagranicznymi kontrahentami i odprawę celną.
Raporty i wydruki oparte na SQL Server Reporting Services obsługują wersje językowe przez parametr kultury przekazywany do szablonu RDL. Szablon pobiera etykiety kolumn z tej samej tabeli tłumaczeń co interfejs, a formatuje daty według kultury odbiorcy. Możliwości tego narzędzia opisuje tekst Microsoft SQL Reporting Services.
Etykieta logistyczna ma dwie warstwy. Dane w kodzie kreskowym, takie jak numer SSCC czy data ważności, są zapisane według identyfikatorów zastosowania GS1 i nie zależą od języka. Tłumaczeniu podlegają tylko opisy czytelne dla człowieka, np. nazwa towaru albo nazwa odbiorcy. Budowę takiej etykiety opisuje artykuł etykieta GS1.

Drukarki Zebra przyjmują szablony w języku ZPL. Domyślne kodowanie drukarki nie obejmuje cyrylicy, dlatego szablon zaczyna się od polecenia ^CI28, które przełącza interpretację danych na UTF-8. Drugim warunkiem jest czcionka zawierająca potrzebne znaki, zwykle wgrana do pamięci drukarki jako plik TrueType. Dobór urządzeń opisuje materiał drukarka kodów kreskowych.
^XA
^CI28
^FO50,50^A@N,40,40,E:ARIALUNI.TTF^FDПалета 001 / Paleta 001^FS
^FO50,110^A@N,30,30,E:ARIALUNI.TTF^FDОдержувач: Łódź Magazyn 2^FS
^XZ
Nazwa pliku czcionki w przykładzie jest przykładowa. Przed wdrożeniem warto wydrukować etykietę testową z pełnym zestawem znaków każdego obsługiwanego języka, bo brakujący znak drukarka zastępuje pustym polem bez komunikatu o błędzie.
Osobną sprawą są nazwy towarów. Pakiet językowy tłumaczy zasoby programu, ale nazwa towaru pochodzi z kartoteki i zwykle przychodzi z ERP w jednym języku. Jeśli etykieta dla odbiorcy zagranicznego ma zawierać nazwę w jego języku, kartoteka potrzebuje tabeli nazw z kolumną kultury, podobnej do tabeli tłumaczeń interfejsu. Przy braku tłumaczenia szablon drukuje nazwę podstawową, a raport kontrolny wskazuje indeksy do uzupełnienia.
Wdrożenie kolejnej wersji językowej
Włączenie kolejnego języka w działającym systemie przebiega podobnie jak inne zmiany w konfiguracji programu magazynowego. SoftwareStudio dodaje pakiety językowe na etapie wdrożenia albo w ramach dalszego rozwoju systemu, dopasowując je do składu zespołu i rynków, na które trafia towar. Obsługa wielu języków nie wymaga odrębnej licencji.
| Etap | Zakres prac |
|---|---|
| Analiza zespołu | ustalenie języków operatorów oraz języków dokumentów dla kontrahentów |
| Przygotowanie tłumaczeń | tłumaczenie kluczy zasobów i konsultacja terminologii z osobami znającymi realia magazynu |
| Konfiguracja | włączenie pakietu, przypisanie języka do kont i szablonów wydruków |
| Test w wybranej strefie | sprawdzenie komunikatów i wydruków w realnej pracy przed objęciem całego magazynu |
Najwięcej uwagi wymaga terminologia. Dosłowne tłumaczenie maszynowe terminów magazynowych bywa niejednoznaczne, bo słowo „lokalizacja” w słowniku ogólnym nie oznacza gniazda regałowego. Pierwszą wersję tłumaczenia może przygotować narzędzie opisane w artykule asystent tłumacza w SoftwareStudio, ale ostateczne brzmienie komunikatów zatwierdza osoba pracująca na hali.
Przed uruchomieniem warto sprawdzić kompletność pakietu zapytaniem, które wyszuka klucze bez tłumaczenia w nowej kulturze. Po starcie produkcyjnym te same zasady obowiązują przy każdym rozszerzeniu systemu, o czym piszemy przy okazji tematu wdrożenie systemu WMS.
-- klucze obecne po polsku, a brakujące w nowej kulturze
SELECT pl.Klucz, pl.Tekst
FROM dbo.Tlumaczenie AS pl
WHERE pl.Kultura = 'pl-PL'
AND NOT EXISTS (SELECT 1 FROM dbo.Tlumaczenie AS t
WHERE t.Klucz = pl.Klucz AND t.Kultura = 'uk-UA');
Grupy z magazynami w kilku krajach korzystają zwykle z jednej instalacji systemu z lokalnymi pakietami językowymi. Taki model dobrze współgra z wariantem magazynu w chmurze, w którym wszystkie oddziały pracują na tej samej bazie, a zarząd dostaje raporty w jednym formacie. Operatorzy wózków w strefach wysokiego składowania czytają te same komunikaty na terminalach pojazdowych, co ma znaczenie przy pracy opisanej w tekście aplikacja dla magazynów wysokiego składowania. Ofertę systemu przedstawia strona program magazynowy WMS.net.




