MapInfo şi harta României - din nou în actualitate
Aşa după cum ştiţi probabil din numerele anterioare ale revistei PCReport,
Microsoft a lansat odată cu Windows 95 şi noul pachet Office pentru Windows 95 ce conţine pe
lângă clasicele Excel, PowerPoint şi Word şi o componentă noua - Schedule. Ceea ce este
însă important pentru utilizatorul de Excel este noua capabilitate a acestui program de a ataşa hărţi
documentelor cu care se lucrează, cu condiţia ca ele sa aibă un câmp comun de “join”.
 |
Harta administrativa a Romaniei
|
Cum se ştie, Microsoft nu este un producător software oarecare, ci se află în top în
acest domeniu. Ceea ce a făcut ca alegerea software-ului de desktop mapping compatibil cu hărţile
ataşate documentelor Excel, să cântărească mult pe piaţa de desktop mapping. Opţiunea
celor de la Microsoft a fost firma MapInfo şi formatul lor de reprezentare hărţi şi date
şi acest lucru nu a mirat pe nimeni deoarece realizările celor de la MapInfo până acum
confirmă poziţia de lider care o au pe piaţa de desktop mapping. După cum (probabil) se
ştie, ei au dezvoltat un mediu propriu de scriere aplicaţii MapBasic ce oferă o unealtă
deosebit de puternică pentru un programator.
Pentru utilizatorul de Excel din România, un ajutor deosebit de util îl constituie harta României 1 :
1 000 000 (Fig. 1) furnizată de Geo Strategies S.A. din Sibiu, firmă ce are ca obiect de
activitate cartografierea digitală. Harta are ca şi informaţii câteva câmpuri utile pentru
administraţie, populate deja cu informaţii veridice. Ceea ce vă propun în continuare este ca
folosind informaţiile dintr-un spreadsheet Excel să actualizăm tabela MapInfo ce conţine
aceasta hartă. (Pentru detalii suplimentare consultaţi articolul din PCReport despre MapBasic).
Idea de la care am pornit a fost să evit toate conversiile posibile de tabele dintr-un format în
altul, folosind facilitatea limbajului MapBasic de a schimba date dinamic cu alte aplicaţii Windows
(DDE). Astfel, tabela RBS.TAB din format MapInfo va fi deschisă în cadrul aplicaţiei şi se
vor scana rând pe rând elementele unei coloane comune de “join” pentru a găsi liniile omoloage
din tabela şi din spreadsheet-ul deja deschis în Excel. Cu informaţii din linia omoloagă se
va actualiza tabela sub MapInfo.
Funcţiile de schimb dinamic de date folosite au cam aceeaşi sintaxă în orice limbaj de
programare sub Windows. Sintaxa lor în MapBasic este următoarea:
DDEinitiate(application_name,topic)
- returnează handler-ul unui canal de comunicaţii deschis sau 0 daca nu se poate iniţia un
schimb de date
DDERequest$(channel, item_name)
- returnează un string reprezentând rezultatul “cererii” item_name de pe canalul channel
DDETerminate channel
- încheie sesiunea ataşată unui canal
DDETerminateAll
- încheie toate sesiunile de comunicare iniţiate anterior
Pentru a putea obţine de la Excel numele spreadsheet-ului deschis trimitem o cerere cu variabila
topic =”topics”. Cum rezultatul diferă de la o versiune la alta, vom analiza string-ul obţinut
şi vom putea decide asupra versiunii Excel (4, 5, 6 sau 7 - mai jos n-am testat). Cu numele de
spreadsheet astfel obţinut se iniţiază o nouă legătură, dar de data aceasta cu
tabelul Excel deschis. Vom presupune că pe prima linie a sa, informaţiile arată astfel:
| ID |
NUME_RES |
JUDETUL |
POPULATIA |
COD_POST |
PREFIX_TEL |
Coloana folosită drept cheie pentru join va fi NUME_RES. De aceea vom căuta printre celulele
primei linii una care să contină această valoare folosind cereri DDERequest$. Daca se găseşte
această coloană, atunci va începe actualizarea propriu-zisă, deschizând mai întâi tabela
MapInfo de actualizat RBS.TAB.
Cu o buclă "while" simplă se va cauta apoi pentru fiecare valoare din câmpul
NUME_RES din RBS.TAB linia pe care aceasta apare în tabelul Excel. Structura bazei de date a tabelei
RBS.TAB este una identică cu cea a documentului Excel. Ceea ce se actualizează în tabel este
valoarea câmpului JUDETUL, însă aceasta poate fi foarte uşor schimbată să putem alege
orice alt câmp.
Este important de urmărit cum se obţine din spreadsheet-ul Excel curent valoarea unei celule. O
simplă cerere (request) către document, menţionând ca topic string-ul ce formează
adresa celulei (de ex. R12C4) furnizează informaţia cerută. Daca nu s-ar specifica decât o
linie sau o coloană, funcţia va returna conţinutul întregii linii sau coloane respective.
În Figura 2. Se poate urmări listing-ul comentat al aplicaţiei scrise in MapBasic 3.0. După
cum se vede, codul este unul foarte apropiat de BASIC, iar secvenţele de lucru cu tabele sunt cele
clasice ale unui SQL. El a fost testat cu succes pe tabele mari de date şi a permis o foarte rapidă
actualizare, evitând astfel operaţii anevoioase de conversii.
Cu cele arătate până aici reiese uşor că orice tabele existente în MapInfo pot fi
actualizate extrem de simplu pe baza informaţiilor din Excel. Trebuie doar puţin efort de scriere
a programului şi apoi totul vine de la sine. Dacă mai şi modifici pe ici-pe colo, acesta
devine un puternic utilitar nu numai de actualizare dar şi de conversie. Succes!
Fig. 2. Listingul Aplicatiei MapBasic 3.0
! Script pentru actualizarea tabelelor
! din MapInfo cu date din Excel
! Cod sursa MapBasic 3.0
! Orice program are o functie principala (gen C)
Declare Sub Main
Sub Main
Dim chan_num, tab_marker, col_number,
row_number, row_in_rbs as INTEGER
Dim topiclist, topicname, cell,
path, to_look, to_update as STRING
Dim ready as LOGICAL
path=”C:\EXCEL\ “
chan_num=DDEInitiate("Excel","System")
if chan_num=0 then
print "Excel not available at this moment
"
print "Check for an Excel instance!"
End Program
end if
topiclist=DDERequest$(chan_num,"topics")
if topiclist="System" then
print "First you must open a valid
spreadsheet in Excel!"
else
! In Excel 4 topiclist poate arata astfel:
! ": C:\Excel\romania.xls Sheet1 System"
! In Excel 5,6 si 7 topiclist poate arata astfel:
! "[Book1]Sheet1 [Book2]Sheet2 ....."
! Vom prelucra sirul pentru a obtine numele spreadsheet-ului
if Left$(topiclist,1)=":" then
tab_marker=InStr(3,topiclist,chr$(9))
if tab_marker=0 then
print
"No Excel document in use!"
End
Program
end if
topicname=Mid$(topiclist,3,tab_marker-3)
else
tab_marker=InStr(1,topiclist,chr$(9))
topicname=Left$(topiclist,tab_marker-1)
end if
DDETerminate chan_num
! Pina aici s-a gasit numele spreadsheet-ului din care vom citi
! Acum incepe sesiunea de actualizare tabela
chan_num=DDEInitiate("Excel",topicname)
if chan_num=0 then
print "There are errors communicating with
"+ topicname
End Program
end if
ready = 0
col_number = 1
! In Excel pe prima linie sunt scrise numele cimpurilor
! Vom cauta coloana NUME_RES care este comuna tabelelor
cell=DDERequest$(chan_num,"R1C"+str$(col_number))
do while (len(cell)<>2)and not ready
if RTrim$(cell)="NUME_RES" then
ready=1
else
col_number=col_number+1
cell=DDERequest$(chan_num,"R1C"+str$(col_number))
end if
loop
if ready=0 then
print "The spreadsheet doesn't have the right
form"
End Program
end if
! Acum incepe pentru fiecare linie din tabela MapInfo
! cautarea sa in spreadsheet-ul Excel .
! Daca s-a gasit valoarea de "join" corecta se va
! face actualizarea coloanei JUDETUL cu valoarea citita din Excel
open table path+"rbs.tab"
fetch first from rbs
row_in_rbs=1
do while not eot(rbs)
to_look=rbs.nume_res
ready=0
row_number=2
cell=DDERequest$(chan_num,"R"+str$(row_number)+"C"+str$(col_number))
do while (len(cell)<>2)and not ready
if RTrim$(cell)=Rtrim$(to_look) then
ready=1
to_update=DDERequest$(chan_num,"R"+str$(row_number)+
"C"+str$(col_number+1))
update rbs set judetul=to_update where rowid=row_in_rbs
else
row_number=row_number+1
cell=DDERequest$(chan_num,"R"+str$(row_number)+"C"+str$(col_number))
end
if
loop
row_in_rbs=row_in_rbs+1
fetch next from rbs
loop
DDETerminateAll
end if
end sub
|
PC Report
Nr.40, Ianuarie 1996
|
|