Hello Barry
I can't guess if the value 17 creating an extraneous column is normal or the result of a data error.
For the tab count, I didn't used your scheme.
In theory, yours is better but when applied in an AppleScript is gave a wrong behavior.
Given AppleScript features, I can't treat the entire file in a single pass with standard AppleScript.
So, I must create a loop treating smaller blocks of datas.
Alas, doing that introduce a new problem.
filling the clipboard and pasting in Numbers requires a lot of time.
with your scheme, replacing spaces by TAB requires less time than the fill clipboard and paste one so there is an annoying confict on pass 2 or worst at the end of the last pass because the last block of data is small so treating it is fast and when it's done, the preceeding paste task isn't achieved.
Other annoying feature, when I create a new document by hand, I may work upon it without AutoSave action but when the doc is created thru a script, AutoSave apply and sometimes a script instruction is executed during an autosave task and in this case, the action applied to Numbers is lost.
Of course, I will report that to Apple.
Here are two versions of a script using standard AppleScript.
You will be able to run them for see.
Be patient, they require several minutes.
With the first one, I was able to treat the original document.
No need to rename it. The script accept the xxx.dat file on entry.
--{code}
--[SCRIPT huge-text-to-Numbers v1]
(*
Enregistrer le script en tant qu’application : huge-text-to-Numbers.app
Il sera très bien sur le bureau.
mode 1 :
Double clic sur “huge-text-to-Numbers.app”
Un dialogue demande de naviguer vers le fichier txt ou dat à traiter
mode 2 :
Glisser déposer l'icône du fichier texte à traiter sur celle de “huge-text-to-Numbers.app”
Dans les deux cas, le script remplace les groupes d'espaces par un caractère TAB.
Les données texte ainsi réorganisées sont collées dans un nouveau document Numbers.
--=====
Save the script as an Application : huge-text-to-Numbers.app
The Desktop would be a good location.
mode 1 :
Double click on “huge-text-to-Numbers.app”
A dialog allow to navigate to the txt or dat file to import.
mode 2 :
Drag and drop the text file icon on the “huge-text-to-Numbers.app” one.
In both cases the script replace chunks of spaces by single TAB character.
Then, the reorganized datas are pasted in a new Numbers document.
--=====
Yvan KOENIG (VALLAURIS, France)
2012-01-05
*)
(*
Use a property to fasten the script *)
property laSource : {}
property leFichier : ""
--=====
script main
local debut, spaces30, nbParagraphes, |texteTraité|, bloc, premierParagrapheDuBloc, dernierParagrapheDuBloc, blocDeTexte, spaces
my activateGUIscripting()
set debut to current date
set my laSource to every paragraph of (read leFichier)
(*
Create a string of 30 spaces characters *)
set spaces30 to ""
repeat 30 times
set spaces30 to spaces30 & space
end repeat
(*
Create a blank Numbers spreadsheet and remove the headers from the default table *)
set myNewDoc to my makeAnIworkDoc("Numbers")
tell application "Numbers" to tell document myNewDoc to tell sheet 1 to tell table 1
removerow 1
removecolumn 1
end tell
(*
Replace every chunks of spaces by a single TAB character *)
set nbParagraphes to count my laSource
set numDuBloc to 1
set premierParagrapheDuBloc to 1
repeat
set dernierParagrapheDuBloc to premierParagrapheDuBloc + 19999
if dernierParagrapheDuBloc > nbParagraphes then set dernierParagrapheDuBloc to nbParagraphes
set blocDeTexte to my recolle(itemspremierParagrapheDuBloc thru dernierParagrapheDuBloc of my laSource, return)
copy spaces30 to spaces
set nbSpaces to 30
repeat
if nbSpaces > 1 then
say "replace groups of " & nbSpaces & " spaces by tab in block " & numDuBloc
else
say "replace every single space by a tab in block " & numDuBloc
end if
set blocDeTexte to my remplace(blocDeTexte, spaces, tab)
if nbSpaces > 1 then
set spaces to text 1 thru -2 of spaces
else
exit repeat
end if
set nbSpaces to nbSpaces - 1
end repeat
say "remove tab from end of paragraphs in block " & numDuBloc
if blocDeTexte ends with tab then set blocDeTexte to text 1 thru -2 of blocDeTexte
set blocDeTexte to my remplace(blocDeTexte, tab & return, return)
tell application "Numbers" to tell document myNewDoc to tell sheet 1 to tell table 1
(*
Create the first row the insertion area *)
repeat
try
add row below last row
exit repeat
on error
delay 0.1
end try
end repeat
(*
Define the insertion area *)
repeat
try
set selection range to range (name of cell 1 of row premierParagrapheDuBloc)
exit repeat
on error
delay 0.1
end try
end repeat
end tell
(*
Copy the datas to the clipboard *)
say "Copy the datas to the clipboard"
set the clipboard toblocDeTexte
say "paste in the table"
my raccourci("Numbers", "v", "cas")
(*
tell application "Numbers" to tell document myNewDoc to tell sheet 1 to tell table 1
(*
Select the first cell of last row *)
set selection range to range (name of cell 1 of last row)
end tell
*)
if dernierParagrapheDuBloc < nbParagraphes then
set numDuBloc to numDuBloc + 1
set premierParagrapheDuBloc to dernierParagrapheDuBloc + 1
else
exit repeat
end if
end repeat
say "Done in " & ((current date) - debut) & " seconds."
end script
--=====
on parleAnglais()
local z
try
tell application "Numbers" to set z to localized string "Cancel"
on error
set z to "Cancel"
end try
return (z is not "Annuler")
end parleAnglais
--=====
on recolle(l, d)
local oTIDs, t
set oTIDs to AppleScript's text item delimiters
set AppleScript's text item delimiters to d
set t to l as text
set AppleScript's text item delimiters to oTIDs
return t
end recolle
--=====
(*
replaces every occurences of d1 by d2 in the text t
*)
on remplace(t, d1, d2)
local oTIDs, l
set oTIDs to AppleScript's text item delimiters
set AppleScript's text item delimiters to d1
set l to text items of t
set AppleScript's text item delimiters to d2
set t to l as text
set AppleScript's text item delimiters to oTIDs
return t
end remplace
--=====
(*
Creates a new iWork document from the Blank template and returns its name.
example:
set myNewDoc to my makeAnIworkDoc(theApp)
*)
on makeAnIworkDoc(the_app)
local maybe, path_to_the_App, nb_doc
if the_app is "Pages" then
tell application "Pages"
set nb_doc to count of documents
makenewdocumentwith properties {template name:item 1 of templates}
end tell
else if the_app is "Numbers" then
tell application "System Events" to the_app is in title of every application process
if not result then activateapplicationtheApp
tell application "System Events"
set path_to_the_App to get application file of application processthe_app
end tell
tell application "Numbers"
set nb_doc to count of documents
open ((path_to_the_App as text) & "Contents:Resources:Templates:Blank.nmbtemplate:")
end tell
else
if my parleAnglais(theApp) then
error "The application “" & the_app & "“ is not accepted !"
else
error "L’application « " & the_app & " » n’est pas gérée !"
end if
end if
tell applicationthe_app
repeat until (count of documents) > nb_doc
delay 0.1
end repeat
name of document 1
end tell -- the_App
return result
end makeAnIworkDoc
--=====
on activateGUIscripting()
(* to be sure than GUI scripting will be active *)
tell application "System Events"
if not (UI elements enabled) then set (UI elements enabled) to true
end tell
end activateGUIscripting
--=====
(*
==== Uses GUIscripting ====
*)
(*
This handler may be used to 'type' text, invisible characters if the third parameter is an empty string.
It may be used to 'type' keyboard raccourcis if the third parameter describe the required modifier keys.
I changed its name « shortcut » to « raccourci » to get rid of a name conflict in Smile.
*)
on raccourci(a, t, d)
local k
activateapplicationa
tell application "System Events" to tell application process a
set frontmost to true
try
t * 1
if d is "" then
key codet
else if d is "c" then
key codetusing {command down}
else if d is "a" then
key codetusing {option down}
else if d is "k" then
key codetusing {control down}
else if d is "s" then
key codetusing {shift down}
else if d is in {"ac", "ca"} then
key codetusing {command down, option down}
else if d is in {"as", "sa"} then
key codetusing {shift down, option down}
else if d is in {"sc", "cs"} then
key codetusing {command down, shift down}
else if d is in {"kc", "ck"} then
key codetusing {command down, control down}
else if d is in {"ks", "sk"} then
key codetusing {shift down, control down}
else if (d contains "c") and (d contains "s") and d contains "k" then
key codetusing {command down, shift down, control down}
else if (d contains "c") and (d contains "s") and d contains "a" then
key codetusing {command down, shift down, option down}
end if
on error
repeat with k in t
if d is "" then
keystroke (k as text)
else if d is "c" then
keystroke (k as text) using {command down}
else if d is "a" then
keystrokekusing {option down}
else if d is "k" then
keystroke (k as text) using {control down}
else if d is "s" then
keystrokekusing {shift down}
else if d is in {"ac", "ca"} then
keystroke (k as text) using {command down, option down}
else if d is in {"as", "sa"} then
keystroke (k as text) using {shift down, option down}
else if d is in {"sc", "cs"} then
keystroke (k as text) using {command down, shift down}
else if d is in {"kc", "ck"} then
keystroke (k as text) using {command down, control down}
else if d is in {"ks", "sk"} then
keystroke (k as text) using {shift down, control down}
else if (d contains "c") and (d contains "s") and d contains "k" then
keystroke (k as text) using {command down, shift down, control down}
else if (d contains "c") and (d contains "s") and d contains "a" then
keystroke (k as text) using {command down, shift down, option down}
end if
end repeat
end try
end tell
end raccourci
--=====
on run
set leFichier to choose file of type {"txt", "dat"} without invisible
run scriptmain
end run
--=====
on open sel
set leFichier to first item of sel
tell application "System Events"
try
set extension_du_nom to name extension of disk item (leFichier as text)
on error
set extension_du_nom to ""
end try
end tell
if extension_du_nom is in {"txt", "dat"} then
run scriptmain
else
set leFichier to ""
if my parleAnglais() then
error "The file" & return & leFichier & return & "isn’t a txt or dat one !"
else
error "Le fichier" & return & leFichier & return & "n’est pas de type .txt ou .dat !"
end if
end if
end open
--=====
--[/SCRIPT]
--{code}
The second one use your scheme to replace the space characters.
As I wrote above, it fails.
But it's interesting to run it to compare the time required to treat a block.
--{code}
--[SCRIPT huge-text-to-Numbers v2]
(*
Enregistrer le script en tant qu’application : huge-text-to-Numbers.app
Il sera très bien sur le bureau.
mode 1 :
Double clic sur “huge-text-to-Numbers.app”
Un dialogue demande de naviguer vers le fichier txt ou dat à traiter
mode 2 :
Glisser déposer l'icône du fichier texte à traiter sur celle de “huge-text-to-Numbers.app”
Dans les deux cas, le script remplace les groupes d'espaces par un caractère TAB.
Les données texte ainsi réorganisées sont collées dans un nouveau document Numbers.
--=====
Save the script as an Application : huge-text-to-Numbers.app
The Desktop would be a good location.
mode 1 :
Double click on “huge-text-to-Numbers.app”
A dialog allow to navigate to the txt or dat file to import.
mode 2 :
Drag and drop the text file icon on the “huge-text-to-Numbers.app” one.
In both cases the script replace chunks of spaces by single TAB character.
Then, the reorganized datas are pasted in a new Numbers document.
In fact, as the code which fix the text is too fast,
there is conflict with the paste task and the treatment fails.
--=====
Yvan KOENIG (VALLAURIS, France)
2012-01-05
*)
(*
Use a property to fasten the script *)
property laSource : {}
property leFichier : ""
--=====
script main
(*
Requires the properties leFichier and laSource *)
local debut, nbParagraphes, bloc, premierParagrapheDuBloc, dernierParagrapheDuBloc, blocDeTexte, spaces
my activateGUIscripting()
set debut to current date
set my laSource to every paragraph of (read leFichier)
(*
Create a blank Numbers spreadsheet and remove the headers from the default table *)
set myNewDoc to my makeAnIworkDoc("Numbers")
tell application "Numbers" to tell document myNewDoc to tell sheet 1 to tell table 1
removerow 1
removecolumn 1
end tell
(*
Replace every chunks of spaces by a single TAB character *)
set nbParagraphes to count my laSource
set numDuBloc to 1
set premierParagrapheDuBloc to 1
repeat
set dernierParagrapheDuBloc to premierParagrapheDuBloc + 9999
if dernierParagrapheDuBloc > nbParagraphes then set dernierParagrapheDuBloc to nbParagraphes
set blocDeTexte to my recolle(itemspremierParagrapheDuBloc thru dernierParagrapheDuBloc of my laSource, return)
say "Start treatment of rows " & premierParagrapheDuBloc & " to " & dernierParagrapheDuBloc
repeat while blocDeTexte contains (space & space)
say "shorten double spaces in block " & numDuBloc
set blocDeTexte to my remplace(blocDeTexte, space & space, space)
end repeat
say "remove space from end of paragraphs in block " & numDuBloc
if blocDeTexte ends with space then set blocDeTexte to text 1 thru -2 of blocDeTexte
set blocDeTexte to my remplace(blocDeTexte, space & return, return)
say "Replace every space character by a tab in block " & numDuBloc
set blocDeTexte to my remplace(blocDeTexte, space, tab)
tell application "Numbers" to tell document myNewDoc to tell sheet 1 to tell table 1
(*
Create the first row of the new block to fill *)
repeat
try
add row below last row
exit repeat
on error
delay 0.1
end try
end repeat
(*
Define the insertion area *)
repeat
try
set selection range to range (name of cell 1 of row premierParagrapheDuBloc)
exit repeat
on error
delay 0.1
end try
end repeat
end tell
(*
Copy the datas to the clipboard *)
say "Copy the datas to the clipboard"
set the clipboard toblocDeTexte
(*
Paste in the table *)
say "paste in the table"
my raccourci("Numbers", "v", "cas")
if dernierParagrapheDuBloc < nbParagraphes then
set numDuBloc to numDuBloc + 1
set premierParagrapheDuBloc to dernierParagrapheDuBloc + 1
else
exit repeat
end if
end repeat
say "Done in " & ((current date) - debut) & " seconds."
end script
--=====
on parleAnglais()
local z
try
tell application "Numbers" to set z to localized string "Cancel"
on error
set z to "Cancel"
end try
return (z is not "Annuler")
end parleAnglais
--=====
on recolle(l, d)
local oTIDs, t
set oTIDs to AppleScript's text item delimiters
set AppleScript's text item delimiters to d
set t to l as text
set AppleScript's text item delimiters to oTIDs
return t
end recolle
--=====
(*
replaces every occurences of d1 by d2 in the text t
*)
on remplace(t, d1, d2)
local oTIDs, l
set oTIDs to AppleScript's text item delimiters
set AppleScript's text item delimiters to d1
set l to text items of t
set AppleScript's text item delimiters to d2
set t to l as text
set AppleScript's text item delimiters to oTIDs
return t
end remplace
--=====
(*
Creates a new iWork document from the Blank template and returns its name.
example:
set myNewDoc to my makeAnIworkDoc(theApp)
*)
on makeAnIworkDoc(the_app)
local maybe, path_to_the_App, nb_doc
if the_app is "Pages" then
tell application "Pages"
set nb_doc to count of documents
makenewdocumentwith properties {template name:item 1 of templates}
end tell
else if the_app is "Numbers" then
tell application "System Events" to the_app is in title of every application process
if not result then activateapplicationtheApp
tell application "System Events"
set path_to_the_App to get application file of application processthe_app
end tell
tell application "Numbers"
set nb_doc to count of documents
open ((path_to_the_App as text) & "Contents:Resources:Templates:Blank.nmbtemplate:")
end tell
else
if my parleAnglais(theApp) then
error "The application “" & the_app & "“ is not accepted !"
else
error "L’application « " & the_app & " » n’est pas gérée !"
end if
end if
tell applicationthe_app
repeat until (count of documents) > nb_doc
delay 0.1
end repeat
name of document 1
end tell -- the_App
return result
end makeAnIworkDoc
--=====
on activateGUIscripting()
(* to be sure than GUI scripting will be active *)
tell application "System Events"
if not (UI elements enabled) then set (UI elements enabled) to true
end tell
end activateGUIscripting
--=====
(*
==== Uses GUIscripting ====
*)
(*
This handler may be used to 'type' text, invisible characters if the third parameter is an empty string.
It may be used to 'type' keyboard raccourcis if the third parameter describe the required modifier keys.
I changed its name « shortcut » to « raccourci » to get rid of a name conflict in Smile.
*)
on raccourci(a, t, d)
local k
activateapplicationa
tell application "System Events" to tell application process a
set frontmost to true
try
t * 1
if d is "" then
key codet
else if d is "c" then
key codetusing {command down}
else if d is "a" then
key codetusing {option down}
else if d is "k" then
key codetusing {control down}
else if d is "s" then
key codetusing {shift down}
else if d is in {"ac", "ca"} then
key codetusing {command down, option down}
else if d is in {"as", "sa"} then
key codetusing {shift down, option down}
else if d is in {"sc", "cs"} then
key codetusing {command down, shift down}
else if d is in {"kc", "ck"} then
key codetusing {command down, control down}
else if d is in {"ks", "sk"} then
key codetusing {shift down, control down}
else if (d contains "c") and (d contains "s") and d contains "k" then
key codetusing {command down, shift down, control down}
else if (d contains "c") and (d contains "s") and d contains "a" then
key codetusing {command down, shift down, option down}
end if
on error
repeat with k in t
if d is "" then
keystroke (k as text)
else if d is "c" then
keystroke (k as text) using {command down}
else if d is "a" then
keystrokekusing {option down}
else if d is "k" then
keystroke (k as text) using {control down}
else if d is "s" then
keystrokekusing {shift down}
else if d is in {"ac", "ca"} then
keystroke (k as text) using {command down, option down}
else if d is in {"as", "sa"} then
keystroke (k as text) using {shift down, option down}
else if d is in {"sc", "cs"} then
keystroke (k as text) using {command down, shift down}
else if d is in {"kc", "ck"} then
keystroke (k as text) using {command down, control down}
else if d is in {"ks", "sk"} then
keystroke (k as text) using {shift down, control down}
else if (d contains "c") and (d contains "s") and d contains "k" then
keystroke (k as text) using {command down, shift down, control down}
else if (d contains "c") and (d contains "s") and d contains "a" then
keystroke (k as text) using {command down, shift down, option down}
end if
end repeat
end try
end tell
end raccourci
--=====
on run
set leFichier to choose file of type {"txt", "dat"} without invisible
run scriptmain
end run
--=====
on open sel
set leFichier to first item of sel
tell application "System Events"
try
set extension_du_nom to name extension of disk item (leFichier as text)
on error
set extension_du_nom to ""
end try
end tell
if extension_du_nom is in {"txt", "dat"} then
run scriptmain
else
set leFichier to ""
if my parleAnglais() then
error "The file" & return & leFichier & return & "isn’t a txt or dat one !"
else
error "Le fichier" & return & leFichier & return & "n’est pas de type .txt ou .dat !"
end if
end if
end open
--=====
--[/SCRIPT]
--{code}
I will post two other scripts in an other message.
Yvan KOENIG (VALLAURIS, France) jeudi 5 janvier 2012
iMac 21”5, i7, 2.8 GHz, 12 Gbytes, 1 Tbytes, mac OS X 10.6.8 and 10.7.2
My iDisk is : http://public.me.com/koenigyvan
Please : Search for questions similar to your own before submitting them to the community
For iWork's applications dedicated to iOS, go to :
https://discussions.apple.com/community/app_store/iwork_for_ios