webForumDet fria alternativet

Läsa in textfil

ASP

28 svar · 1 582 visningar · startad av devotion

Medlem sedan jan. 20013 582 inlägg
Frågan#1

Hej!

Nu är det panik.... Någon som kan hjälpa...??

Jag har en textfil

Som är uppbyggd så här:

020061016          EIOpris
100000040EKKJ 1X10/10             20061017
20100019700 ACD 
20300039700 0013
20600012445 F00 
21100036000 00AA
21200046300+01C 
300778

Första raden är en startrad. Attt det är första raden kan man se genom att den börjar på 0 (noll)

Andra raden är artikelraden. Det kan man se genom att den börjar på 1 (ett)

Nästkommande rader är prisrader. Det kan man se genom att de börjar på 2 (två)

Sista raden är en slutrad det kan man se genom att den börjar på 3 (tre)

Nu ska jag försöka förklara hur det ligger till.. ;)

Raden:

100000040EKKJ 1X10/10             20061017

innehåller artikelnummer och benämning informationen skall in i tblPrice

De nästföljande raderna:

20100019700 ACD 
20300039700 0013
20600012445 F00 
21100036000 00AA
21200046300+01C

innehåller leverantör samt pris på artikeln. Detta ska in i tblPrice tillsamamns med artikelnumret från den raden som börjar på 1 (ett)

Det hela hänger ihop kan man säga...

Hur ska jag göra?

Jag vet hur jag skriver till databas och läser från textfil samt plockar ut strängarna... Det är bara logiken jag behöver ha hjälp med... :)

Mvh
Henrik

Medlem sedan dec. 19996 721 inlägg
#2

Gör en yttre loop som loopar över raderna, samt en inre loop som du hoppar in i så fort du stöter på en rad som börjar på "1". I den inre loopen ackumulerar du de databasfrågor som ska köras för artikeln och när du sen stöter på nästa "1"-rad så exekverar du den ackumulerade uppdateringen och tömmer den, inför nästa looprunda.

Medlem sedan dec. 20025 483 inlägg
#3

Nu har visserligen emission givit ett svar, men eftersom jag påbörjade ett ihopskriveri innan det kom till kännedom, postar jag någonting du kanske kan utgå från

set o = createobject("scripting.filesystemobject")
set f = o.opentextfile("foo.text", 1)

f.skipline 'ej intresserad av den första raden

set r = new regexp
r.pattern = "^\d(\d{8})([^\s]{25})(\d{8})"
set m = r.execute(f.readline)

if not (m.count > 0) then
  response.write "Fel på regex!"
  response.end
end if

tenr  = m(0).submatches(0) 'e-nummer
tterm = m(1).submatches(0) 'benämning
tdate = m(2).submatches(0) 'prisändr.datum

r.pattern = "^(\d)(\d{2})(\d{8})([\+- \?])([^\s]+)"

do while not f.atendofstream
 set m = r.execute(f.readline)
 if not (m.count > 0) then exit do
 'm(0).submatches(0) -> grossistkod
 'm(1).submatches(0) -> grossistpris
 'm(2).submatches(0) -> status
 'm(3).submatches(0) -> rabattkod
loop

set r = nothing

f.close
Medlem sedan jan. 20013 582 inlägg
#4

Peter S... skulle du kunna förklara lite vad koden gör?

och fattas det inte en loop...

Borde det inte som emission skrev vara en yttre och inre loop?

Mvh
Henrik

Medlem sedan dec. 20025 483 inlägg
#5

Den första regexp:en hämtar ut de olika delarna på rad #2, enligt specen. Dessa placeras sedan i t-variablerna (bra namn, eller hur? Eller vänta nu...). Regexp #2 appliceras därefter på varje återstående rad till dess att den fallerar på den sista raden i filen.

I det här fallet ser det inte ut att behövas en inre loop.

Koden är dock otestad.

Medlem sedan jan. 20013 582 inlägg
#6

Jag kanske är lite fundersam eftersom jag har mer info....

Jag tyckte jag förklarade så bra.... :r

Men det finns 80 000 artiklar i filen

Det finns bara EN rad som börjar på 0 (noll)

sedan finns det massor av artikelrader som börjar på 1 (ett)

och ännu fler prisrader som börjar på 2 (två)

Sist finns en slutrad som börjar på 3 (tre)

020061016          EIOpris
100000040EKKJ 1X10/10             20061017
20100019700 ACD 
20300039700 0013
20600012445 F00 
21100036000 00AA
21200046300+01C 
100000045EKKJ 1X10/10             20061017
20100017900 ACD 
20300035900 0013
20600012445 F00 
21100034900 00AA
21200044100+01C 
100000049EKKJ 1x10/10             20061017
21200027900+01C 
100000060EKKJ 2X2,5/2,5           20061017
20100010300 ACA 
20300019600 0013
20600006187 F00 
21100019200 00AA
100000065EKKJ 2X2,5/2,5           20061017
20100009200 ACA 
20300017800 0013
20600006187 F00 
21100017000 00AA
100000070EKKJ 2X4/4               20061017
20100013100 ACB 
20300028000 0013
21100025000 00AA
100000075EKKJ 2X4/4               20061017
20100011800 ACB 
20300025400 0013
21100023900 00AA
100000080EKKJ 2X6/6               20061017
20100018400 ACC 
20300037000 0013
21100033300 00AA
100000085EKKJ 2X6/6               20061017
20100016400 ACC 
20300033400 0013
21100031900 00AA
100000090EKKJ 2X10/10             20061017
20100029800 ACD 
20300060400 0013
21100052900 00AA
100000095EKKJ 2X10/10             20061017
20100026700 ACD 
20300053900 0013
21100050600 00AA
100000110EKKJ 3X2,5/2,5           20061017
20100005850 AC1 
20200011700 Q202
20300011200 0013
20600003267 D00 

...

osv.

...

300778

Mvh
Henrik

Medlem sedan dec. 20025 483 inlägg
#7

Kika på denna:

set o = createobject("scripting.filesystemobject")
set f = o.opentextfile("foo.text", 1)

f.skipline 'ej intresserad av den första raden

dim tenr, tterm, tdate

do while not f.atendofstream
 line = f.readline

 if left(line, 1) = "1" then

   r.pattern = "^\d(\d{8})([^\s]{25})(\d{8})"
   set m = r.execute(line)
   tenr  = m(0).submatches(0) 'e-nummer
   tterm = m(1).submatches(0) 'benämning
   tdate = m(2).submatches(0) 'prisändr.datum

 elseif left(line, 1) = "2"

   r.pattern = "^\d(\d{2})(\d{8})([\+- \?])([^\s]+)"
   set m = r.execute(f.readline)
   'm(0).submatches(0) -> grossistkod
   'm(1).submatches(0) -> grossistpris
   'm(2).submatches(0) -> status
   'm(3).submatches(0) -> rabattkod

 end if
loop

set r = nothing

f.close
Medlem sedan jan. 20013 582 inlägg
#8

Aha!

Jag tycker dock fortfarande att det saknas något... I den första regexpen ska det ju skrivas till tblArticle.. I den andra till tblPrice.. men, då måste jag ju få med en koppling till artikeln i tblArtcle, dvs jag måste få med enummer även till den andra skrivningen dvs till tblPrice...

eller har jag (som vanligt) fattat fel?

Mvh
Henrik

Medlem sedan dec. 20025 483 inlägg
#9

Den informationen finns i de globala t-variablerna :)

Medlem sedan jan. 20013 582 inlägg
#10

Aha!

Och hur skulle då databasskrivningen se ut... Jag är verkligen inte på banan... :)

Mvh
Henrik

Medlem sedan dec. 20025 483 inlägg
#11

Typ

dim tenr, tterm, tdate

do while not f.atendofstream
 line = f.readline

 if left(line, 1) = "1" then

   r.pattern = "^\d(\d{8})([^\s]{25})(\d{8})"
   set m = r.execute(line)
   tenr  = m(0).submatches(0) 'e-nummer
   tterm = m(1).submatches(0) 'benämning
   tdate = m(2).submatches(0) 'prisändr.datum

   conn.execute "insert into foo values ("& tenr &", "& tterm &", "& tdate &")",,128

 elseif left(line, 1) = "2"

   r.pattern = "^\d(\d{2})(\d{8})([\+- \?])([^\s]+)"
   set m = r.execute(f.readline)
   'm(0).submatches(0) -> grossistkod
   'm(1).submatches(0) -> grossistpris
   'm(2).submatches(0) -> status
   'm(3).submatches(0) -> rabattkod

   conn.execute "insert into bar values([red]"& tenr &"[/red],...)",,128

 end if
loop
Medlem sedan jan. 20013 582 inlägg
#12

Aha okej... då tror jag att jag är med.. :)

men varför är:

r.pattern = "^\d(\d{2})(\d{8})([\+- \?])([^\s]+)"
   set m = r.execute(f.readline)
   'm(0).submatches(0) -> grossistkod
   'm(0).submatches(1) -> grossistpris
   'm(0).submatches(2) -> status
   'm(0).submatches(3) -> rabattkod

bortkommenterat?

Är inte det också variabler?

Mvh
Henrik

Medlem sedan dec. 20025 483 inlägg
#13

Jag ville endast förtydliga vad de innehåller :)

Medlem sedan jan. 20013 582 inlägg
#14

okej.. då ska jag provköra....

mvh
Henrik

Medlem sedan dec. 20025 483 inlägg
#15

Koden är uppdaterad eftersom jag upptäckte ett fel.

Medlem sedan jan. 20013 582 inlägg
#16

okidoki.. har inte komit så långt än.. ;)

Medlem sedan jan. 20013 582 inlägg
#17

Hej igen! :)

Det fungerar ju fint! :D

Lite följdfrågor bara. Varför använder du regexp Peter S och inte bara en "loop-lösning" som emission föreslog.... Hur kan man annars göra? Fördelar och nackdelar?

Mvh
Henrik

Medlem sedan dec. 20025 483 inlägg
#18

Tjena! :)

Jag använder regex eftersom det i detta fall är lämpligt, ty filens format är känt i förväg och ett reguljärt uttryck gör det enkelt att plocka ut de intressanta fälten.

Vad gäller fördelar tycker jag regex är mer lättläst. Vilket alternativ som är mer effektivt låter jag vara osagt -- gör en testcase vettja! :D

Looplösningen låter jag emission själv beskriva.

Upptäckte också något ytterligare fel i ovanstående kod, bl.a. ett uteblivit 'then', men det verker du ju ha upptäckt.

Medlem sedan jan. 20013 582 inlägg
#19

Okej! :)

Vi får väl se om den gode emission svarar!... ;)

Mvh
Henrik

Medlem sedan jan. 20013 582 inlägg
#20

Hej på er!

Nu har jag följande kod som fungerar nästan..

<%@LANGUAGE="VBSCRIPT" CODEPAGE="1252"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
</head>
<%
' Öppna databasen
' ***************
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.ConnectionString = Application("sConn")
objConn.Open

set objFSO = createobject("scripting.filesystemobject")

set objFile = objFSO.opentextfile(server.mappath("/prisfiler/eio/eio.txt"), 1)

objFile.skipline 'ej intresserad av den första raden

set r = new regexp

dim sArticleNumber, sArticleName, dPriceDate

do while not objFile.atendofstream

sline = objFile.readline
 
 if left(sLine, 1) = "1" then

   r.pattern = "^\d(\d{8})(.{25})(\d{8})"
   set m = r.execute(sLine)
   sArticleNumber = m(0).submatches(0) 'e-nummer
   sArticleName = trim(m(0).submatches(1)) 'benämning
   dPriceDate = m(0).submatches(2) 'prisändr.datum
   
	sSQL = "insert into tblEioArticles (articleNumber, articleName) values ('"& sArticleNumber &"', '"& sArticleName &"')"
	'response.write sSQL
	'response.End()
   objConn.Execute sSQL,,128

 elseif left(sLine, 1) = "2" then

   r.pattern = "^\d(\d{2})(\d{8})([\+\- \?])([^\s]+)"
   set m = r.execute(objFile.readline)
   sSupplierNumber = m(0).submatches(0) 'grossistkod
   iSupplierPrice = cdbl(m(0).submatches(1)) 'grossistpris
   sStatus = m(0).submatches(2) 'status
   sDiscountCode = m(0).submatches(3) 'rabattkod
	
	sSQL = "insert into tblEioPrice (articleNumber, articleSupplierId, articlePrice) values ('"& sArticleNumber &"', '"& sSupplierNumber &"', " & iSupplierPrice & ")"
   objConn.execute sSQL,,128

 end if
loop

set r = nothing

objFile.close

set objFile = nothing
set objFSO = nothing
objConn.Close
Set objConn = Nothing
%>

<body>
</body>
</html>

Problemet är att det blir lite fel.. ;)

Det blir endast två poster som läses in enligt bifogad bild. Sedan får jag följande fel:

Feltyp:
Körningsfel i Microsoft VBScript (0x800A0005)
Ogiltigt proceduranrop eller argument.
/articles/EIO.asp, line 46

Varför blir det så här...??

Mvh
Henrik

test.png
254 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2
119 ms — deklarationer (db)
0 ms — hämta statistik (cache)
132 ms — hämta tråd, inlägg och bilagor (db)
120 ms — ändringar (db)