'Fast text search (hash table / GLib) 'by TJF ≫ Sep 26, 2011 12:16 'https://www.freebasic.net/forum/viewtopic.php?f=7&t=18558&p=163893&hilit=glib+hash#p163893 ' This is file HashTable_glib.bas, an example for GLib Hash tables ' (C) 2011 by Thomas[ dot ]Freiherr[ at ]gmx{ dot }net ' License GPLv 3 ' ' See for details ' http://developer.gnome.org/glib/2.28/glib-Hash-Tables.html #INCLUDE ONCE "glib.bi" ' Define some keys (FB keywords) / Definiere Keys (hier FB Befehle) ' いくつかのキー(FB キーワード)を定義する。演算子 @ (のアドレス) Static As ZString Const Ptr FBKEY(...) = { _ @"ABS",@"ACCESS",@"ACOS",@"ALIAS",@"ALLOCATE",@"ALPHA",@"AND", _ @"ANDALSO",@"ANY",@"APPEND",@"ASSERT",@"ASSERTWARN",@"ASC", _ @"ASIN",@"ASM",@"ATAN2",@"ATN", _ @"BASE",@"BEEP",@"BIN",@"BINARY",@"BIT",@"BITRESET",@"BITSET", _ @"BLOAD",@"BSAVE", _ @"CALL",@"CALLOCATE",@"CASE",@"CAST",@"CBYTE",@"CDBL",@"CDECL", _ @"CHAIN",@"CHDIR",@"CHR",@"CINT",@"CIRCLE",@"CLASS",@"CLEAR", _ @"CLNG",@"CLNGINT",@"CLOSE",@"CLS",@"COLOR",@"COM",@"CONS", _ @"COMMAND",@"COMMON",@"CONDBROADCAST",@"CONDCREATE",@"CONDDESTROY", _ @"CONDSIGNAL",@"CONDWAIT",@"CONST",@"CONSTRUCTOR",@"CONTINUE", _ @"COS",@"CPTR",@"CSHORT",@"CSIGN",@"CSNG",@"CSRLIN",@"CUBYTE", _ @"CUINT",@"CULNG",@"CULNGINT",@"CUNSG",@"CURDIR",@"CUSHORT", _ @"CUSTOM",@"CVD",@"CVI",@"CVL",@"CVLONGINT",@"CVS",@"CVSHORT", _ @"DATA",@"DATE",@"DATEADD",@"DATEDIFF",@"DATEPART",@"DATESERIAL", _ @"DATEVALUE",@"DAY",@"DEALLOCATE",@"DECLARE",@"DEFBYTE",@"DEFDBL", _ @"DEFINT",@"DEFLNG",@"DEFLNGINT",@"DEFSHORT",@"DEFSNG",@"DEFSTR", _ @"DEFUBYTE",@"DEFUINT",@"DEFULNGINT",@"DEFUSHORT",@"DELETE", _ @"DESTRUCTOR",@"DIM",@"DIR",@"DO",@"DRAW",@"DYNAMIC", _ @"DYLIBFREE",@"DYLIBLOAD",@"DYLIBSYMBOL", _ @"ELSE",@"ELSEIF",@"ENCODING",@"END",@"ENUM",@"ENVIRON",@"ESCAPE", _ @"EOF",@"EQV",@"ERASE",@"ERFN",@"ERL",@"ERMN",@"ERR",@"ERROR", _ @"EXEC",@"EXEPATH",@"EXIT",@"EXP",@"EXPLICIT",@"EXPORT",@"EXTERN", _ @"FALSE",@"FBOOLEAN",@"FIELD",@"FILEATTR",@"FILECOPY",@"FILEDATETIME", _ @"FILEEXISTS",@"FILELEN",@"FIX",@"FLIP",@"FOR",@"FORMAT",@"FRAC", _ @"FRE",@"FREEFILE",@"FUNCTION", _ @"GET",@"GETJOYSTICK",@"GETKEY",@"GETMOUSE",@"GOSUB",@"GOTO", _ @"HEX",@"HIBYTE",@"HIWORD",@"HOUR", _ @"IF",@"IIF",@"IMAGECONVERTROW",@"IMAGECREATE",@"IMAGEDESTROY",@"IMP", _ @"IMPORT",@"INKEY",@"INP",@"INPUT",@"INPUT$",@"INSTR",@"INSTRREV", _ @"INT",@"IS",@"ISDATE", _ @"KILL", _ @"LBOUND",@"LCASE",@"LEFT",@"LEN",@"LET",@"LIB",@"LPT",@"LINE", _ @"LOBYTE",@"LOC",@"LOCAL",@"LOCATE",@"LOCK",@"LOF",@"LOG", _ @"LOOP",@"LOWORD",@"LPOS",@"LPRINT",@"LSET",@"LTRIM", _ @"MID",@"MINUTE",@"MKD",@"MKDIR",@"MKI",@"MKL",@"MKLONGINT",@"MKS", _ @"MKSHORT",@"MOD",@"MONTH",@"MONTHNAME",@"MULTIKEY",@"MUTEXCREATE", _ @"MUTEXDESTROY",@"MUTEXLOCK",@"MUTEXUNLOCK", _ @"NAME",@"NAMESPACE",@"NOKEYWORD",@"NEXT",@"NEW",@"NOT",@"NOW", _ @"OCT",@"OFFSETOF",@"ON",@"ONCE",@"OPEN",@"OPTION",@"OPERATOR", _ @"OR",@"ORELSE",@"OUT",@"OUTPUT",@"OVERLOAD", _ @"PAINT",@"PALETTE",@"PASCAL",@"PCOPY",@"PEEK",@"PIPE",@"PMAP", _ @"POINT",@"POINTER",@"POKE",@"POS",@"PRESERVE",@"PRESET",@"PRINT", _ @"PRIVATE",@"PROCPTR",@"PROPERTY",@"PROTECTED",@"PSET",@"PTR", _ @"PUBLIC",@"PUT", _ @"RANDOM",@"RANDOMIZE",@"READ",@"REALLOCATE",@"REDIM",@"REM", _ @"RESET",@"RESTORE",@"RESUME",@"RETURN",@"RGB",@"RGBA",@"RIGHT", _ @"RMDIR",@"RND",@"RSET",@"RTRIM",@"RUN", _ @"SADD",@"SCOPE",@"SCRN",@"SCREEN",@"SCREENCOPY",@"SCREENCONTROL", _ @"SCREENEVENT",@"SCREENINFO",@"SCREENGLPROC",@"SCREENLIST", _ @"SCREENLOCK",@"SCREENPTR",@"SCREENRES",@"SCREENSET",@"SCREENSYNC", _ @"SCREENUNLOCK",@"SECOND",@"SEEK",@"SELECT",@"SETDATE",@"SETENVIRON", _ @"SETMOUSE",@"SETTIME",@"SGN",@"SHARED",@"SHELL",@"SIN", _ @"SIZEOF",@"SLEEP",@"SPACE",@"SPC",@"SQR",@"STATIC", _ @"STDCALL",@"STEP",@"STOP",@"STR",@"STRING",@"STRPTR",@"SUB", _ @"SWAP",@"SYSTEM",@"SHR",@"SHL", _ @"TAB",@"TAN",@"THEN",@"THIS",@"THREADCREATE",@"THREADWAIT", _ @"TIME",@"TIMESERIAL",@"TIMEVALUE",@"TIMER",@"TO",@"TRANS", _ @"TRIM",@"TRUE",@"TYPE", _ @"UBOUND",@"UCASE", _ @"UNION",@"UNLOCK",@"UNSIGNED",@"UNTIL",@"USING", _ @"VA_ARG",@"VA_FIRST",@"VA_NEXT",@"VAL",@"VALLNG",@"VALINT", _ @"VALUINT",@"VALULNG",@"VAR",@"VARPTR",@"VIEW", _ @"WAIT",@"WBIN",@"WCHR",@"WEEKDAY",@"WEEKDAYNAME",@"WEND", _ @"WHILE",@"WHEX",@"WIDTH",@"WINDOW",@"WINDOWTITLE",@"WINPUT", _ @"WITH",@"WOCT",@"WRITE",@"WSPACE",@"WSTR",@"WSTRING", _ @"XOR",@"YEAR", _ @"AS",@"BYREF",@"BYVAL", _ @"BYTE",@"UBYTE",@"SHORT",@"USHORT",@"LONG",@"ULONG", _ @"INTEGER",@"UINTEGER",@"LONGINT",@"ULONGINT", _ @"SINGLE",@"DOUBLE",@"ZSTRING"} ' Search for a key, output error message if not exist (value = 0) ' Sucht Key _K_ und meldet Fehler wenn nicht vorhanden (Value = 0) ' ★キーを検索し、存在しない場合はエラーメッセージを出力(値= 0)★ ' ★演算子 * (の値) ' g_hash_table_lookup (GHashTable *hash_table, gconstpointer key) #DEFINE check(_T_, _K_) _ If g_hash_table_lookup(_T_, _K_) = 0 Then _ Print "エラー、キーワードが見つかりません: "; *_K_ ' Callback for output: value first, then key ' Callback zur Ausgabe: erst Value, dann Key ' 出力のコールバック:キーと値 Sub HashOut Cdecl( _ ByVal key As gpointer, _ ByVal value As gpointer, _ ByVal user_data As gpointer) ' key を Ptr に型変換して、値とともに表示 Print *Cast(ZString Ptr, key),GPOINTER_TO_INT(value) End Sub ' ***** main / Hauptprogramm ***** Dim i As Integer ' Create new hash table / Neue HashTable erstellen ' ★新しいハッシュテーブルを作成★ ' 演算子 @ (のアドレス) ' g_str_hash (gconstpointer v) 文字列をハッシュ値に変換します。 ' g_str_equal (gconstpointer v1, gconstpointer v2) 2つの文字列をバイト毎に比較して、等しい場合は TRUE を返します。 Var table = g_hash_table_new(@g_str_hash, @g_str_equal) ' Insert keys and values / Fuellen mit den Keys und Values ' ★キーと値を挿入★ Print "キーの件数:"; UBound(FBKEY); " 何かキー入力で、テーブルに登録したキーと、キーのアドレス、値を表示します。" Sleep For i As Integer = 0 To UBound(FBKEY) g_hash_table_insert(table, FBKEY(i), GINT_TO_POINTER(i + 1000)) Print *FBKEY(i), FBKEY(i), i + 1000 Next i Print Print "最後のキーの値:"; g_hash_table_lookup(table, FBKEY(UBound(FBKEY))); 'キーの存在を確認 Print " 何かキー入力で、登録した全てのキーと値を表示します。" Sleep ' Replace an existing key / Ersetzen eines vorhandenen Keys (6 x) ' 既存のキーを置き換える ' 注:g_hash_table_insert は古い値を破壊する ' g_hash_table_replace は古い値とキーを破壊する For i = 0 To 5 'g_hash_table_insert (GHashTable *hash_table, gpointer key, gpointer value) g_hash_table_insert(table, @"UBYTE", GINT_TO_POINTER(i - 999999)) Next i ' Check if all keys are available / Pruefen ob alle Keys vorhanden ' すべてのキーが使えるかどうか確認 For i As Integer = 0 To UBound(FBKEY) check(table, FBKEY(i)) Next i ' Print all keys and values / Alle Keys und Values ausgeben ' すべてのキーと値を表示する ' g_hash_table_foreach (GHashTable *hash_table, GHFunc func:キーと値のペアを引数にして呼び出す関数, gpointer user_data:func に引き渡すユーザ・データ) ' (*GHFunc) (gpointer key, gpointer value, gpointer user_data) g_hash_table_foreach(table, @HashOut, 0) ' Search for a non existing key / Suche einen nicht vorhandenen Key Print Print "既存のキー以外を検索した結果の表示例です。何かキー入力で終了します。" Print ' 演算子 @ (のアドレス) check(table, @"FreeBasic-Portal") ' Destroy table, release memory / Tabelle aufloesen, Speicher freigeben ' テーブルを破棄、メモリを解放 g_hash_table_unref(table) Sleep
'Fast text search (hash table / GLib) 'by TJF ≫ Sep 26, 2011 12:16 'https://www.freebasic.net/forum/viewtopic.php?f=7&t=18558&p=163893&hilit=glib+hash#p163893 ' See for details ' http://developer.gnome.org/glib/2.28/glib-Hash-Tables.html #Include Once "glib.bi" Dim Shared KeyArray(500000) As String Dim Shared As Integer Counter, i, j, k, l Dim As Single t1,t2 Dim collisions As Integer Dim accumulation As Integer ' ***** main / Hauptprogramm ***** ' Create new hash table / Neue HashTable erstellen ' ★新しいハッシュテーブルを作成★ ' g_hash_table_new (GHashFunc hash_func, GEqualFunc key_equal_func) ' 演算子 @ (のアドレス) ' g_str_hash (gconstpointer v) 文字列をハッシュ値に変換します。 ' g_str_equal (gconstpointer v1, gconstpointer v2) 2つの文字列をバイト毎に比較して、等しい場合は TRUE を返します。 Var HashTable = g_hash_table_new(@g_str_hash, @g_str_equal) t1=Timer Counter = 0 collisions = 0 accumulation = 0 ' Insert keys and values / Fuellen mit den Keys und Values ' ★キーと値を挿入★ 'g_hash_table_insert(HashTable, @!"AAC\0", GINT_TO_POINTER(987654)) 'g_hash_table_insert(HashTable, @!"ZAC\0", GINT_TO_POINTER(876543)) For i = Asc("A") To Asc("Z") Print Chr(i) + Space(1); For j = Asc("A") To Asc("Z") For k = Asc("A") To Asc("Z") For l = Asc("A") To Asc("Z") Counter = Counter + 1 'ReDim Preserve KeyArray(Counter + 1) 'KeyArray(Counter) = Chr(i) + Chr(j) + Chr(k) + Chr(l) KeyArray(Counter) = Chr(i, j, k, l) 'StrPtr(KeyArray(Counter)) returns a ZSTRING PTR to the content of the STRING. If g_hash_table_lookup(HashTable, StrPtr(KeyArray(Counter))) = 0 Then accumulation = accumulation + 1 'g_hash_table_insert (GHashTable *hash_table, gpointer key, gpointer value) 'GLib には、int から gpointer へ正確にキャストする GINT_TO_POINTER というマクロと、 'gpointer から int へ正確にキャストする GPOINTER_TO_INT というマクロが定義されています。 g_hash_table_insert(HashTable, StrPtr(KeyArray(Counter)), GINT_TO_POINTER(Counter)) Else 'キーの重複が発生したら表示する 'Display when duplicate keys occur collisions += 1 Print Print g_hash_table_lookup(HashTable, StrPtr(KeyArray(Counter))) , Counter, KeyArray(Counter) Sleep End If Next l Next k Next j Next i t2=Timer Print Print Print "最終登録のキー:";KeyArray(accumulation), "キーに与えた値:" ;g_hash_table_lookup(HashTable, StrPtr(KeyArray(accumulation))) Print Print "終了しました。 KeyArray = "; KeyArray(Counter); " 処理件数 = 26^4(456,976) = "; Counter 'Print "Finished. Last KeyArray = "; KeyArray(Counter); " Counter = 26^4(456,976) = "; Counter Print "衝突件数 = ";collisions," 登録件数 = ";accumulation 'Print "collisions = ";collisions," accumulation = ";accumulation Print Print "所要秒数 = ";t2 - t1 'Print "Required seconds = ";t2 - t1 ' Destroy table, release memory / Tabelle aufloesen, Speicher freigeben ' テーブルを破棄、メモリを解放 g_hash_table_unref(HashTable) Sleep
'Fast text search (hash table / GLib) 'by TJF ≫ Sep 26, 2011 12:16 'https://www.freebasic.net/forum/viewtopic.php?f=7&t=18558&p=163893&hilit=glib+hash#p163893 ' See for details ' http://developer.gnome.org/glib/2.28/glib-Hash-Tables.html #Include Once "glib.bi" Dim Shared KeyArray(12000000) As String Dim Shared As Integer Counter, i, j, k, l, m Dim As Single t1,t2,t3 Dim collisions As Integer Dim accumulation As Integer Dim KeyString As String ' ***** main / Hauptprogramm ***** ' Create new hash table / Neue HashTable erstellen ' ★新しいハッシュテーブルを作成★ ' g_hash_table_new (GHashFunc hash_func, GEqualFunc key_equal_func) ' 演算子 @ (のアドレス) ' g_str_hash (gconstpointer v) 文字列をハッシュ値に変換します。 ' g_str_equal (gconstpointer v1, gconstpointer v2) 2つの文字列をバイト毎に比較して、等しい場合は TRUE を返します。 Var HashTable = g_hash_table_new(@g_str_hash, @g_str_equal) t1=Timer Counter = 0 collisions = 0 accumulation = 0 ' Insert keys and values / Fuellen mit den Keys und Values ' ★キーと値を挿入★ 'g_hash_table_insert(ArrayItemID, @!"AAC\0", GINT_TO_POINTER(987654)) 'g_hash_table_insert(ArrayItemID, @!"ZAC\0", GINT_TO_POINTER(876543)) For i = Asc("A") To Asc("Z") Print Chr(i) + Space(1); For j = Asc("A") To Asc("Z") For k = Asc("A") To Asc("Z") For l = Asc("A") To Asc("Z") For m = Asc("A") To Asc("Z") Counter = Counter + 1 'KeyString = Chr(i, j, k, l) KeyString = Chr(i, j, k, l, m) KeyArray(Counter) = KeyString If g_hash_table_lookup(HashTable, SAdd(KeyArray(Counter))) = 0 Then accumulation = accumulation + 1 'g_hash_table_insert (GHashTable *hash_table, gpointer key, gpointer value) 'GLib には、int から gpointer へ正確にキャストする GINT_TO_POINTER というマクロと、 'gpointer から int へ正確にキャストする GPOINTER_TO_INT というマクロが定義されています。 g_hash_table_insert(HashTable, SAdd(KeyArray(Counter)), GINT_TO_POINTER(Counter)) '★3★★★★★★★★★★★ '上で HashTable を作るときに配列を使う点がポイント。何故か文字列データを直接使うと連想配列ができない 'Print KeyString,g_hash_table_lookup(HashTable, SAdd(KeyString)) 'Sleep 'Print KeyString, g_hash_table_lookup(HashTable, SAdd(KeyString)) 'Sleep Else 'キーの重複が発生したら表示する 'Display when duplicate keys occur collisions += 1 Print Print g_hash_table_lookup(HashTable, SAdd(KeyArray(Counter))) , Counter, KeyArray(Counter) Sleep End If Next m Next l Next k Next j Next i t2=Timer Print Print Print "最終登録のキー:";KeyString, "キーに与えた値:" ;g_hash_table_lookup(HashTable, SAdd(KeyString)) Print Print "終了しました。 KeyString = "; KeyString; " 処理件数 = 26^5(11,881,376) = "; Counter 'Print "Finished. Last ItemID = "; ItemID(Counter); " Counter = 26^4(456,976) = "; Counter Print "衝突件数 = ";collisions," 登録件数 = ";accumulation 'Print "collisions = ";collisions," accumulation = ";accumulation Print Print "登録所要秒数 = ";t2 - t1 'Print "Required seconds = ";t2 - t1 Print '**************************************************************** 'Hash によるデータの照合チェック '**************************************************************** For i = Asc("A") To Asc("Z") Print Chr(i)+Space(1); For j = Asc("A") To Asc("Z") For k = Asc("A") To Asc("Z") For l = Asc("A") To Asc("Z") For m = Asc("A") To Asc("Z") KeyString = Chr(m, l, i, j, k) 'KeyString = Chr(i, j, k, l) 'Print KeyString, g_hash_table_lookup(HashTable, SAdd(KeyString)) '上で HashTable を作るときに配列を使う点がポイント 'Sleep Counter = g_hash_table_lookup(HashTable, SAdd(KeyString)) If KeyString <> KeyArray(Counter) Then ' Hash を使ってデータを照合 'データの不整合が発生したら表示する Print Print "Inconsistent data", KeyString, g_hash_table_lookup(HashTable, SAdd(KeyString)) Sleep End If Next m Next l Next k Next j Print "Consistent data", KeyString, g_hash_table_lookup(HashTable, SAdd(KeyString)) Next i Print t3=Timer Print "照合所要秒数 = ";t3 - t2 Print Print "合計所要秒数 = ";t3 - t1 ' Destroy table, release memory / Tabelle aufloesen, Speicher freigeben ' テーブルを破棄、メモリを解放 g_hash_table_unref(HashTable) Sleep
'品目マスタと品目オーダを照合して品目別受注量を集計 'Fast text search (hash table / GLib) 'by TJF ≫ Sep 26, 2011 12:16 'https://www.freebasic.net/forum/viewtopic.php?f=7&t=18558&p=163893&hilit=glib+hash#p163893 ' See for details ' http://developer.gnome.org/glib/2.28/glib-Hash-Tables.html #Include Once "glib.bi" '★1★★★★★★★★★★★ ' Create new hash table / Neue HashTable erstellen ' ★新しいハッシュテーブルを作成★ ' g_hash_table_new (GHashFunc hash_func, GEqualFunc key_equal_func) ' 演算子 @ (のアドレス) ' g_str_hash (gconstpointer v) 文字列をハッシュ値に変換します。 ' g_str_equal (gconstpointer v1, gconstpointer v2) 2つの文字列をバイト毎に比較して、等しい場合は TRUE を返します。 Var MasterItemID = g_hash_table_new(@g_str_hash, @g_str_equal) '★2★★★★★★★★★★★ Var OrderItemID = g_hash_table_new(@g_str_hash, @g_str_equal) '★2★★★★★★★★★★★ Dim STARTT As Long Dim ENDTIME As Long Dim Minut As Integer Dim Shared ItemID(20000) As String Dim Shared OrderLine(20000) As String Dim Shared OrderItem As String Dim Shared Region As String Dim Shared Price As String Dim Shared Weight As String Dim Shared Counter As Integer Dim Shared collisions As Integer Dim i As Integer Dim QuantityString As String Dim Amount As String Dim Dimension As Integer Dim cellString As String Dim file_name As String Dim file_num As Integer Dim CharacterString As String Dim Regions As Integer Dim ItemMasterNo As Integer Dim IntegratedNo As Integer Dim Orders As Integer Dim Shared ItemMasterArray(20000,3) As String 'Region, price, weight Dim Shared IntegratedOrderArray(20000,5) As String 'Region, ItemID, Quantity, Amount, Weight Dim Shared SortArray(20000) As String '**************************************************************** '**************************************************************** '★★★多次元配列を複数列を使ってソート★★★ 'How to sort datasheet (x-dim array) by a few columns (at once in 1 loop) ? 'by badidea ≫ Dec 15, 2019 21:54 'https://www.freebasic.net/forum/viewtopic.php?f=3&t=27993&start=30#p266914 'by fxm ≫ Jun 25, 2020 6:49 'https://www.freebasic.net/forum/viewtopic.php?f=3&p=273475&sid=547977eb5d3cc9cf3e6ee7323616cff3#p273475 #Include "crt/stdlib.bi" #Include "string.bi" '------------------------------- class: row_type ------------------------------- Type row_type Dim As String col(Any) Declare Operator Cast () As String End Type Operator row_type.cast () As String Dim As String tempStr For i As Integer = 1 To UBound(col) If i = 1 Then tempStr &= col(i) Else tempStr &= !"\t" & col(i) Next Return tempStr End Operator '------------------------------ class: sort_type ------------------------------- Type sort_type Dim As Short column Dim As Short direction Declare Constructor() Declare Constructor(column As Short, direction As Short) End Type 'a stupid constructor Constructor sort_type() this.column = 0 this.direction = 0 End Constructor 'another stupid constructor Constructor sort_type(column As Short, direction As Short) this.column = column this.direction = direction End Constructor '------------------------------ class: data_type ------------------------------- Type data_type Static As sort_type sortOrder(1 To 3) Dim As Integer numRows, numCols Dim As row_type row(Any) Declare Constructor(numRows As Integer, numPivotMS As Integer) Declare Destructor() Declare Sub copyTo(dst As data_type) Declare Sub sort(sort1st As sort_type, sort2nd As sort_type, sort3rd As sort_type) Declare Static Function qSortCallback Cdecl(pRow1 As row_type Ptr, pRow2 As row_type Ptr) As Long End Type Dim As sort_type data_type.sortOrder(1 To 3) Constructor data_type(numRows As Integer, numCols As Integer) ReDim row(numRows) this.numCols = numCols For iRow As Integer = 1 To numRows ReDim (row(iRow).col)(numCols) 'weird syntax, compiler wants the extra ( ) Next End Constructor Destructor data_type() For iRow As Integer = 1 To numRows Erase row(iRow).col Next Erase row End Destructor Sub data_type.sort(sort1st As sort_type, sort2nd As sort_type, sort3rd As sort_type) 'disable invalid sort filters sortOrder(1) = IIf(sort1st.column < 1 Or sort1st.column >= numCols, sort_type(0,0), sort1st) sortOrder(2) = IIf(sort2nd.column < 1 Or sort2nd.column >= numCols, sort_type(0,0), sort2nd) sortOrder(3) = IIf(sort3rd.column < 1 Or sort3rd.column >= numCols, sort_type(0,0), sort3rd) qsort(@row(1), UBound(row), SizeOf(row_type), CPtr(Any Ptr, @qSortCallback)) End Sub Function data_type.qSortCallback Cdecl(pRow1 As row_type Ptr, pRow2 As row_type Ptr) As Long For i As Integer = 1 To 3 With sortOrder(i) Select Case .direction Case +1 If pRow1->col(.column) < pRow2->col(.column) Then Return -1 If pRow1->col(.column) > pRow2->col(.column) Then Return +1 Case -1 If pRow1->col(.column) > pRow2->col(.column) Then Return -1 If pRow1->col(.column) < pRow2->col(.column) Then Return +1 Case Else 'skip, including direction = 0 End Select End With Next Return 0 End Function '**************************************************************** '**************************************************************** 'Print "Read ""ItemMaster.csv"" and store each line in MasterItemID, ItemID()." Print """ItemMaster.csv"" を読み込んで MasterItemID, ItemID() に登録" '**************************************************************** Print file_name = "ItemMaster.csv" file_num = FreeFile( ) '' 有効なファイル番号を検索します '' ファイルを開きます。そして、ファイル番号をそれに結び付けます。エラーが有れば、抜けます。 If( Open( file_name For Input As #file_num ) ) Then Print "ERROR: 開こうとしたファイル名 " ; file_name Sleep End -1 End If Counter = 0 collisions = 0 Do Until Eof( file_num ) '' ファイルの端に達するまで、繰り返します。 Counter = Counter + 1 ItemID(Counter) ="": Region ="": Price ="" : Weight ="" Line Input #file_num, CharacterString '' テキストの行を読みます。 ItemID(Counter) = Left(CharacterString,3) Region = Mid(CharacterString,6,InStrRev(CharacterString,"""")-6) Price = Mid(CharacterString,InStrRev(CharacterString,"""")+2,InStrRev(CharacterString,",")-InStrRev(CharacterString,"""")-2) Weight = Right(CharacterString,Len(CharacterString)-InStrRev(CharacterString,",")) If g_hash_table_lookup(MasterItemID, StrPtr(ItemID(Counter))) = 0 Then '★4★★★★★★★★★★★ 'g_hash_table_insert (GHashTable *hash_table, gpointer key, gpointer value) 'GLib には、int から gpointer へ正確にキャストする GINT_TO_POINTER というマクロと、 'gpointer から int へ正確にキャストする GPOINTER_TO_INT というマクロが定義されています。 g_hash_table_insert(MasterItemID, StrPtr(ItemID(Counter)), GINT_TO_POINTER(Counter)) '★3★★★★★★★★★★★ ItemMasterArray(Counter,1) = Region ItemMasterArray(Counter,2) = Price ItemMasterArray(Counter,3) = Weight Else 'キーの重複が発生したら表示する 'Display when duplicate keys occur collisions += 1 Print Print g_hash_table_lookup(MasterItemID, StrPtr(ItemID(Counter))) , Counter, ItemID(Counter) Sleep End If Loop 'Print "Numbers of Item Master = ";Counter Print "品目マスタの件数 = ";Counter Print 'Print "Contents of the last Item Master : ";CharacterString ' 画面に最終行を出力します。 Print "品目マスタの最後のデータの内容 : ";CharacterString ' 画面に最終行を出力します。 Print ItemID(Counter) , Region , Price , Weight Print Close #file_num '' ファイル番号を通したファイルを閉じます。 '**************************************************************** '**************************************************************** 'Print "Read ""OrderList.csv"" and compare it with MasterItemID to aggregate price and weight by item and region." Print """OrderList.csv"" を読み込み、MasterItemID と照合して、品目毎に数量・金額・重量を IntegratedOrderArray に集計します。" '**************************************************************** Print Open "OrderItemError.csv" For Output As #1 file_name = "OrderList.csv" file_num = FreeFile( ) '' 有効なファイル番号を検索します '' ファイルを開きます。そして、ファイル番号をそれに結び付けます。エラーが有れば、抜けます。 If( Open( file_name For Input As #file_num ) ) Then Print "ERROR: 開こうとしたファイル名 " ; file_name Sleep End -1 End If Counter = 0 Orders = 0 STARTT=Val(Left(Time,2))*3600+Val(Mid(Time,4,2))*60+Val(Right(Time,2)) Do Until Eof( file_num ) '' ファイルの端に達するまで、繰り返します。 CharacterString = "" : OrderItem = "" : QuantityString = "" Line Input #file_num, CharacterString '' テキストの行を読みます。 Orders = Orders + 1 OrderItem = Left(CharacterString,3) QuantityString = Right(CharacterString,Len(CharacterString)-InStrRev(CharacterString,",")) If g_hash_table_lookup(MasterItemID, StrPtr(OrderItem)) = 0 Then '★4★★★★★★★★★★★ 'Print OrderItem, g_hash_table_lookup(MasterItemID, StrPtr(OrderItem)) 'Sleep 'エラー出力 Print #1, CharacterString Else ItemMasterNo = g_hash_table_lookup(MasterItemID, StrPtr(OrderItem)) 'ItemMasterArray(20000,3) 'Region, price, weight 'IntegratedOrderArray(20000,5) 'Region, ItemID, Quantity, Amount, Weight Region = ItemMasterArray(ItemMasterNo,1) Amount = Str(Val(QuantityString)*Val(ItemMasterArray(ItemMasterNo,2))) Weight = Str(Val(QuantityString)*Val(ItemMasterArray(ItemMasterNo,3))) If g_hash_table_lookup(OrderItemID, StrPtr(OrderItem)) = 0 Then '★4★★★★★★★★★★★ Counter = Counter + 1 OrderLine(Counter) = OrderItem g_hash_table_insert(OrderItemID, StrPtr(OrderLine(Counter)), GINT_TO_POINTER(Counter)) '★3★★★★★★★★★★★ IntegratedOrderArray(Counter,1) = Region IntegratedOrderArray(Counter,2) = OrderItem IntegratedOrderArray(Counter,3) = QuantityString IntegratedOrderArray(Counter,4) = Amount IntegratedOrderArray(Counter,5) = Weight 'Print Counter,Region,ItemID,QuantityString,Amount,Weight 'sleep Else IntegratedNo = g_hash_table_lookup(OrderItemID, StrPtr(OrderItem)) IntegratedOrderArray(IntegratedNo,3) = Str(Val(IntegratedOrderArray(IntegratedNo,3))+Val(QuantityString)) IntegratedOrderArray(IntegratedNo,4) = Str(Val(IntegratedOrderArray(IntegratedNo,4))+Val(Amount)) IntegratedOrderArray(IntegratedNo,5) = Str(Val(IntegratedOrderArray(IntegratedNo,5))+Val(Weight)) 'Print IntegratedNo,ItemID,QuantityString,Amount,Weight 'sleep End If End If Loop 'Print "Number of orders in the list : ";Orders Print "リスト中のオーダ件数 : ";Orders Print ENDTIME = Val(Left(Time,2))*3600+Val(Mid(Time,4,2))*60+Val(Right(Time,2)) Minut=(ENDTIME-STARTT)\60 'Print Using "processing time: ## minutes ## seconds"; Minut; (ENDTIME-STARTT)-Minut*60 Print Using "処理時間: ## 分 ## 秒"; Minut; (ENDTIME-STARTT)-Minut*60 Print Close #1 Close #file_num '' ファイル番号を通したファイルを閉じます。 '**************************************************************** '**************************************************************** ' Destroy table, release memory / Tabelle aufloesen, Speicher freigeben ' テーブルを破棄、メモリを解放 g_hash_table_unref(MasterItemID) '★5★★★★★★★★★★★ g_hash_table_unref(OrderItemID) '★5★★★★★★★★★★★ '**************************************************************** '**************************************************************** 'Print "Sort the totaled results by Region and ItemID." Print "集計結果を、地域順・品目コード順に並び替えます。" '**************************************************************** Print Dim As Integer numRows = Counter, numCols = 5 Var myData = data_type(numRows, numCols) For iRow As Integer = 1 To Counter With myData.row(iRow) For iCol As Integer = 1 To UBound(.col) .col(iCol) = IntegratedOrderArray(iRow,iCol) Next End With Next iRow myData.sort(sort_type(1, +1), sort_type(2, +1), sort_type(0, 0)) For iRow As Integer = 1 To Counter With myData.row(iRow) For iCol As Integer = 1 To UBound(.col) IntegratedOrderArray(iRow,iCol) = .col(iCol) Next End With Next iRow '**************************************************************** '**************************************************************** 'Print "Out put the sorted results to ""OrderSorting.csv""" Print "集計結果を ""OrderSorting.csv"" として出力します。" '**************************************************************** Print 'IntegratedOrderArray(20000,5) 'Region, ItemID, Quantity, Amount, Weight Open "OrderSorting.csv" For Output As #1 For i = 1 To Counter CharacterString = "" For Dimension =1 To 5 cellString = IntegratedOrderArray(i,Dimension) If Dimension = 1 Then cellString = """" & cellString & """" EndIf If Dimension > 1 Then cellString = "," & cellString EndIf CharacterString = CharacterString & cellString Next Dimension Print #1, CharacterString Next i Close #1 '**************************************************************** '**************************************************************** 'Print "Output of the sorted order aggregate has been completed." Print "集計結果のリスト出力が完了しました。" Print "*******************************************************" 'Print "Please enter any key to exit." Print "何かキー入力すると終了します。" Sleep