-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathclass_excell_cell.prg
278 lines (233 loc) · 6.7 KB
/
class_excell_cell.prg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
DEFINE CLASS Excell_Cell AS Custom
ColumnNumber = 0
RowNumber = ''
FoxproFieldType = ''
Value = 0
ZeroDateString = .F.
&& Errors
ErrorCount = 0
ErrorLogPath = ''
ErrorXMLChars = .F.
ErrorXMLCharsText = 'Terdapat karakter yang tidak di-support format XML';
+CHR(10)+CHR(13)+'REF: http://www.w3.org/TR/REC-xml/#charsets'
ErrorExtendedAscii = .F.
ErrorExtendedAsciiText = 'Terdapat karakter Extended ASCII';
+CHR(10)+CHR(13)+'REF: http://docs.oracle.com/cd/E25054_01/relnotes.1111/e17596/toc.htm#sthref5'
&& Menampilkan Error kalo ada karakter di luar standard Xml
ShowErrorXmlChars = .T.
&& Menampilkan Error kalo ada karakter Entended Ascii
ShowErrorExtendedAscii = .T.
PROCEDURE Init
This.ErrorLogPath = SYS(2023) + '\FOX' + SYS(3) + '.LOG'
ENDPROC
FUNCTION ErrorLog
LPARAMETERS sText
This.ErrorCount = This.ErrorCount + 1
STRTOFILE(sText+CHR(13), This.ErrorLogPath, .T.)
ENDFUNC
FUNCTION ErrorShow
IF This.ErrorCount = 0 THEN
RETURN .F.
ENDIF
IF This.ErrorXMLChars AND This.ShowErrorXmlChars THEN
MESSAGEBOX(This.ErrorXMLCharsText;
+CHR(10)+CHR(13)+'LOG: '+This.ErrorLogPath)
ENDIF
IF This.ErrorExtendedAscii AND This.ShowErrorExtendedAscii THEN
MESSAGEBOX(This.ErrorExtendedAsciiText;
+CHR(10)+CHR(13)+'LOG: '+This.ErrorLogPath)
ENDIF
ENDFUNC
FUNCTION GetFieldValueString
lcFieldType = This.FoxproFieldType
This.Value = This.Value
DO CASE
CASE lcFieldType = 'C'
IF VARTYPE(This.Value) = 'X'
&& .NULL.
RETURN ''
ELSE
RETURN This.HTMLEncode(This.Value)
ENDIF
CASE lcFieldType = 'N'
IF VARTYPE(This.Value) = 'X'
&& .NULL.
RETURN '0'
ELSE
RETURN LTRIM(STR(This.Value))
ENDIF
CASE lcFieldType = 'D'
IF VARTYPE(This.Value) = 'X'
&& .NULL.
IF This.ZeroDateString = .T. THEN
RETURN ' - -'
ELSE
RETURN LTRIM(STR(0))
ENDIF
ELSE
IF This.ZeroDateString = .T. AND YEAR(This.Value) = 0 THEN
RETURN ' - -'
ELSE
RETURN LTRIM(STR(This.Value - DATE(1899,12,30)))
ENDIF
ENDIF
OTHERWISE
ERROR 'Undefined foxpro field type ' + lcFieldType
ENDCASE
RETURN ''
ENDFUNC
&& @link http://www.w3.org/TR/REC-xml/#charsets
&& @notes character yang disupport oleh standard internasional:
&& 9, 10, 13, 32-55295, 57344-65533, dan 65536-1114111
FUNCTION IsXmlChars
LPARAMETERS iCharAsc
IF INLIST(iCharAsc, 9, 10, 13) ;
OR BETWEEN(iCharAsc, 32, 55295) ;
OR BETWEEN(iCharAsc, 57344, 65533) ;
OR BETWEEN(iCharAsc, 65536, 1114111) ;
THEN
RETURN .T.
ELSE
RETURN .F.
ENDIF
ENDFUNC
&& @link http://msdn.microsoft.com/en-us/library/9hxt0028%28v=vs.80%29.aspx
&& @notes ascii range 128-255
FUNCTION IsExtendedAscii
LPARAMETERS iCharAsc
IF BETWEEN(iCharAsc, 128, 255) THEN
RETURN .T.
ELSE
RETURN .F.
ENDIF
ENDFUNC
&& @link https://en.wikipedia.org/wiki/Character_encodings_in_HTML
&& @notes XML character references
&& & & (ampersand, U+0026)
&& < < (less-than sign, U+003C)
&& > > (greater-than sign, U+003E)
&& " " (quotation mark, U+0022)
&& ' ' (apostrophe, U+0027)
FUNCTION HTMLEncode
LPARAMETERS sText
LOCAL i, j, sTextResult, sChar, iCharAsc
sTextResult = ''
sText = RTRIM(sText)
FOR i = 1 TO LEN(sText)
sChar = SUBSTR(sText, i, 1)
iCharAsc = ASC(sChar)
&& XML Supported characters
IF This.IsXmlChars(iCharAsc) = .F. THEN
This.ErrorXMLChars = .T.
This.ErrorLog('Excell_Cell.HTMLEncode IsXmlChars ' + LTRIM(STR(iCharAsc)) + ' ' + sChar)
ENDIF
&& Extended ASCII Characters
IF This.IsExtendedAscii(iCharAsc) = .T. THEN
This.ErrorExtendedAscii = .T.
This.ErrorLog('Excell_Cell.HTMLEncode IsExtendedAscii ' + LTRIM(STR(iCharAsc)) + ' ' + sChar)
ENDIF
DO CASE
&& HTML Special Characters
CASE sChar = '&'
sChar = '&'
CASE sChar = '<'
sChar = '<'
CASE sChar = '>'
sChar = '>'
CASE sChar = '"'
sChar = '"'
CASE sChar = "'"
sChar = '''
&& Space + Keyboard One-Stroke Characters
CASE BETWEEN(iCharAsc, 32, 126)
&& Not Encoded. For what 0 to 127 looks like,
&& see http://msdn.microsoft.com/en-us/library/60ecse8t%28v=vs.80%29.aspx
OTHERWISE
sChar = '&#' + PADL(iCharAsc, 4, '0') + ';'
ENDCASE
sTextResult = sTextResult + sChar
ENDFOR
RETURN sTextResult
ENDFUNC
FUNCTION GetColumnNameFromNumber
LOCAL lnReminder, lcResult, lnLength
lnNumber = This.ColumnNumber
lcResult = ''
lnLength = 1
DO WHILE .T.
lnReminder = MOD(lnNumber , 26)
lnResult = FLOOR(lnNumber / 26)
IF lnReminder = 0
lcResult = 'Z' + lcResult
ELSE
lcResult = CHR(64 + lnReminder) + lcResult
ENDIF
lnLength = lnLength + 1
lnNumber = lnResult
IF lnResult =< 26
IF lnResult > 0
IF lnReminder > 0
lcResult = CHR(64 + lnResult) + lcResult
ELSE
IF lnResult > 1
lcResult = CHR(64 + lnResult - 1) + lcResult
ENDIF
ENDIF
ENDIF
EXIT
ENDIF
ENDDO
RETURN lcResult
ENDFUNC
FUNCTION GetExcellFieldType
&& lcFoxproFieldType
&& A Array (only returned when the optional 1 parameter is included)
&& C Character, Varchar, Varchar (Binary)
&& D Date
&& G General
&& L Logical
&& M Memo
&& N Numeric, Float, Double, or Integer
&& O Object
&& Q Blob, Varbinary
&& S Screen
&& T DateTime
&& U Undefined type of expression or cannot evaluate expression.
&& Y Currency
&& lcExcellCellDataType
&& const TYPE_STRING2 = 'str';
&& const TYPE_STRING = 's';
&& const TYPE_FORMULA = 'f';
&& const TYPE_NUMERIC = 'n';
&& const TYPE_BOOL = 'b';
&& const TYPE_NULL = 's';
&& const TYPE_INLINE = 'inlineStr';
&& const TYPE_ERROR = 'e';
DO CASE
CASE This.FoxproFieldType = 'C'
RETURN 't="str"'
CASE This.FoxproFieldType = 'N'
RETURN 't="n"'
CASE This.FoxproFieldType = 'D'
IF This.ZeroDateString = .T. AND YEAR(This.Value) = 0 THEN
RETURN 't="str"'
ELSE
RETURN 's="1" t="n"'
ENDIF
CASE This.FoxproFieldType = 'T'
OTHERWISE
ERROR 'Undefined foxpro field type ' + This.FoxproFieldType
ENDCASE
RETURN 't="str"'
ENDFUNC
FUNCTION ToString
LOCAL lcRange, lcType, lcValue
lcRange = 'r="' ;
+ This.GetColumnNameFromNumber() ;
+ This.RowNumber ;
+ '"'
lcType = This.GetExcellFieldType()
lcValue = This.GetFieldValueString()
RETURN '<c ' + lcRange + ' ' + lcType + '><v>' + lcValue + '</v></c>'
ENDFUNC
ENDDEFINE