Re: [閒聊] 近況 + JavaScript

作者: laechan (揮淚斬馬雲)   2021-11-11 17:59:49
寫個近況。
最近一個需要諭知全公司的人知道的東西,是好幾個 EXCEL
檔,每個檔裡頭各有一些欄位資料,大致上是 A<->B 間的
對照,而 A 有 A1, A2, ... 等欄位,B 有 B1, B2, .. 等
欄位。
這時,比方我想查的東西,剛好分散在好幾個 EXCEL 檔裡頭
,查起來很麻煩,用 javascript 會簡單很多:
1.這些檔都另存 .csv
2.寫一支 htm 檔,開頭就去讀取這些 .csv 的東西,存成一
個叫做 tmps 的字串陣列,每個元素都是每個 csv 檔的每一
行:
var tmps=[];
var fso=new ActiveXObject("filesystemobject");
for(i=0;i<dirs.length;i++)
{
f=fso.OpenTextFile("D:\\"+i+".csv");
csv=f.ReadAll();
f.close();
tmps.push(csv.split("\n"));
}
這樣 tmps 就是我要的全域變數
通常 tmps 還可以 tmps.sort(); 一下
3.宣告兩個全域變數
var data1={};
var data2={};
data1 用來儲存 A 資料的各欄位,使用 mapping 的儲存格
式,比方其資料結構如下
data1[A1][A2][A3]...
它的做法很單純,就是去對每一個 tmps[i] 做必要的拆解:
for(i=0;i<tmps.length;i++)
{
ab=tmps[i].split("A資料與B資料間的分隔字串");
// 這樣 ab[0] = A資料, ab[1] = B資料
// 先處理 data1
a=ab[0].split("\t");
if(typeof(data1[a[0]])=="undefined")
data1[a[0]]={};
if(typeof(data1[a[0]][a[1]])=="undefined")
data1[a[0]][a[1]]={};
.
.
// 再處理 data2
b=ab[1].split("\t");
if(typeof(data2[b[0]])=="undefined")
data2[b[0]]={};
if(typeof(data2[b[0]][b[1]])=="undefined")
data2[b[0]][b[1]]={};
.
.
}
4.有了 tmps 及 data1、data2,就可以很簡單的做下拉式
查詢介面,既可由 A 查 B,也可由 B 查 A。例如使用者
想由 A 查 B,它下拉了 A1、A2、A3 三項,然後按下查
詢按紐,該按紐 on_click='search_a_b();'
function search_a_b()
{
s1=document.getElementById("s1").value;
s2=document.getElementById("s2").value;
s3=document.getElementById("s3").value;
// 當然實際不會這樣寫,這裡只是簡單說明
// 產生比對用字串
ss=s1+"\t"+s2+"\t"+s3;
// 然後去跟 tmps 裡面的每一筆做比對
str="";
for(i=0;i<tmps.length;i++)
{
ab=tmps[i].split("A資料與B資料間的分隔字串");
// 因為是由 A 查 B 所以比對目標放在 ab[0];
if(ab[0].indexOf(ss)==-1) continue;
// 比對到符合的
str+=tmps[i].replace(/\t/g,"&emsp;")+"<BR>";
}
document.write(str);
}
它會將所有符合該三項下拉選項的結果都列出來,比方 A 資料
其實有 A1~A5 五個可下拉項,使用者只下拉前三個時,它就把
只要符合前三項即可的都列出來。
例如說,以異特龍為例,牠所屬的界、門、綱如下
界: 動物界
門: 脊索動物門
綱: 蜥形綱
牠所屬的目、科、屬如下
總目: 恐龍總目
目: 鳥臀目
科: 劍龍科
亞科: 劍龍亞科
屬: 劍龍屬
名字: 異特龍
那前面的界門綱就相當於 A 資料,目科屬就相當於 B 資料。
那比方我要由 A 查 B,分別下拉動物界、脊索動物門、蜥形綱,
按下查詢,那它就應該要顯示的資料:
動物界 脊索動物門 蜥形綱 ←→ 恐龍總目 鳥臀目 劍龍科 劍龍亞科 劍龍屬 異特龍
上面的 ss 變數就是 "動物界\t脊索動物門\t蜥形綱",它就會去
比對每一個 tmps[i] 裡頭的字串,有沒有跟 ss match 的,有的
話,就把該行 document.write 出來。
則這時假設我只下拉前兩個,它自然會把所有有符合前兩個的都列
出,例如光脊索動物門就又有很多分支:
https://i.imgur.com/Zv0coMN.jpg
我寫好這個東西後,把 htm 檔丟到公司內網再告知同單位的同事
有這個東西,則只要知道這東西的人,就不用再去 EXCEL 一個一
個點開來看,只要透過該 htm 的查詢介面,即可輕鬆查詢出想知
道的結果,而且可透過這樣的綜覽,明確知道公司想告訴我們的事
它日後的更新也很方便,每一次的更新就是夾帶一些 EXCEL 檔,
將它們指定目錄另存 .csv,大概一兩分鐘吧就通通另存完畢,然
後 htm 查詢介面就能查到最新的結果。
進一步來說,還可以寫樹狀顯示,這個利用 mapping 及 <table>
標籤的容許彈性來做即可,以資料A 的樹狀結構為例:"
str="<table>";
a1=Object.keys(data1);
for(i1=0;i1<a1.length;i1++)
{
str+="<tr><td>"+a1[i1]+"</td></tr>";
a2=Object.keys(data1[a1[i1]]);
for(i2=0;i2<a2.length;i2++)
{
str+="<tr><td></td><td>"+a2[i2]+"</td></tr>";
a3=Object.keys(data1[a1[i1]][a2[i2]]);
for(i3=0;i3<a3.length;i3++)
{
str+="<tr><td></td><td></td><td>"+a3[i3]+"</td></tr>";
.
.
}
}
}
// 表格的好處就是每一行累加字串最後只要有 </tr> 就不會出錯
str+="</table>";
document.write(str);
這樣出來的資料就類似
xx1
xx11
xx111
xx112
.
.
xx12
xx121
xx122
xx1221
xx1222
.
.
xx123
.
.
.
.
xx2
xx21
xx211
.
.
即全部的資料依樹狀的方式顯示於同一個 htm 頁面,這時手動
按 ctrl-f 去看資料位在哪也是可以,進階寫法就透過展開按鈕
對 style="display:none/block" 做切換,即可實現樹狀結構的
展開及縮回。
熟悉 mapping 的話,這些不用花多少時間就能寫出來。
我的感觸就是,要給全公司看的東西,原始資料不應該如此分散
,這次的經驗可應用在很多地方。
我目前僅剩一件事情令我覺得心煩,這個月要面對,希望能順利
,渡過了就沒事了,應該會繼續把 confarea.htm 完工。這東西
的缺點是無法寫成線上網頁,但如果放到 github 的話則大家都
可以下載,我蠻希望以後有人真的能下載然後利用它寫聖殿的區
域。
其它沒啥事,晚上預計做個備份。
LAechan

Links booklink

Contact Us: admin [ a t ] ucptt.com