I have some temp-tables in my script that I will be exporting to a csv file. I need to also export the field names as well as their values. How can I get the field names of temp-tables?
Here's a quick and dirty example of what you're asking for:
define temp-table tt1
field f1 as character
field f2 as decimal
.
def var iCnt as integer no-undo.
create tt1.
assign
tt1.f1 = "f1"
tt1.f2 = 123.456
.
do icnt = 1 to buffer tt1:num-fields:
display buffer tt1:buffer-field(icnt):name
buffer tt1:buffer-field(icnt):buffer-value
with down
.
down.
end.
Related
I have a text field in a table where I need to substitute phone numbers where applicable.
For example the text field could have:
Call me on 08588812885 immediately
Call me on 07525812845
I need assistance please contact me
Good service
Sometimes a phone number will be in the text but not always and the phone number entered will always be different.
Is there a measure to use to replace the phone numbers with no text.
Ideally the solution would be Power BI, but can also be done in the raw data using excel or VBA
Regular expression in VBA (excel) or Python (Power BI) is a straightforward solution.
I have never used PowerBI with Python before but manage to make following python script.
In PowerBI transformation steps I created a new column that would copy [message] columns and named it [noPhoneNumber], then next step ran this python script
import re
def removePhone(x):
return re.sub('\d{10,11}', "**number removed**", x)
length = len(dataset["noPhoneNumber"])
for iRow in range(length):
dataset["noPhoneNumber"][iRow] = removePhone(dataset["noPhoneNumber"][iRow])
so column "noPhoneNumber"
Call me on 08588812885 immediately
Call me on 07525812845
I need assistance please contact me
Good service
becomes
Call me on **number removed** immediately
Call me on **number removed**
I need assistance please contact me
Good service
In VBA Preferable create UDF (user defined function) and don't create a subroutine, that would be too error prone for this kind of problem.
[Added]
If you need to make a Excel based solution, you can create a UDF function like so:
(remember early binding to import of VBScript_RegExp_55.RegExp in excel)
Function removePhoneNumber(text As String, Optional replacement As String = "**number removed**") As String
Dim regex As New RegExp
regex.Pattern = "\d{10,11}"
removePhoneNumber = regex.Replace(text, replacement)
End Function
...and then use excel function like so:
=removePhoneNumber(A2),
=removePhoneNumber(A3)
and so on...
A simple VBA function alternative
Function removePhone(s As String) As String
Const DELIM As String = " "
Dim i As Long, tokens As Variant
tokens = Split(s, DELIM)
For i = LBound(tokens) To UBound(tokens)
If IsNumeric(tokens(i)) Then
tokens(i) = "*Removed*" ' << change to your needs
Exit For ' assuming a single phone number per string
End If
Next
removePhone = Join(tokens, DELIM)
End Function
You can do this in Power Query. Create a custom column with this below code. I have considered the column name is Comments but please adjust this with your column name.
if Text.Length(Text.Select([comments], {"0".."9"})) = 11
then
Text.Replace(
[comments],
Text.Select([comments], {"0".."9"}),
""
)
else [comments]
Here is the output below. You can also replace phone numbers with other text like #### to make is anonymous.
NOTE
This will only work if there are only 1 number in the string with length 11 (You can adjust the length in code as per requirement).
This will Not work if there are more than one Numbers in the string.
If there are 1 number in the string but length not equal 11, this will keep the whole string as original.
I want to create this particular cell array. I don't want to do it manually,
a = {'1. ','2. ','3. ','4. ', ........upto length(txt)}
I thought of create initially numbers with 1:length(txt) and append it to '.' to create cell array a, But I am facing many errors there.
So that I can use erase function with argument as a
erase(txt,a), where txt contains these numbers at the starting as an example it goes as
1. xxxxxxxxxxxxxxxxxxxxxxxxxxx
2. yyyyyyyyyyyyyyyyyyyyyyyyyyy
3. zzzzzzzzzzzzzzzzzzzzzzzzzzz
So on......
So the output when I run erase will be like
xxxxxxxxxxxxxxxxxxxxxxxxxxx
yyyyyyyyyyyyyyyyyyyyyyyyyyy
zzzzzzzzzzzzzzzzzzzzzzzzzzz
Just use strings.
match = (1:length(txt)) + ". ";
Now you can use erase just like before.
Got it
dotspace = '. '
for k = 1:length(txt)
match{k} = [num2str(k,'%d') dotspace];
end
I am trying to write code in Matlab that will allow me to do the following. There is a part of the code that generates an array D and uses an input file to create this structure called EEG which contains a lot of information. Specifically I am interested in a "labels" field of the chanlocs field of the EEG structure. It contains entries like 'F7', 'F8', 'FP1'... and 17 such entries. The array D that is generated also contains entries like this but in a different order.
So for e.g. D = ['F7','F8', 'FP1'] and EEG.chanlocs.labels = ['FP1','F7','F8']
they contain the same entries but they are in a different order and for what I am trying to do the order is important.
What I basically want to do is to have Matlab scan all entries of D and find that particular index of EEG.chanlocs.labels to which that entry corresponds.
Example: If D(1) = 'F7' I want it to return for e.g. i = 2 because F7 is the 2nd entry in EEG.chanlocs.labels. In this way I want it to scan all of D and return the indices in EEG.chanlocs.labels.
What I have tried so far is:
for i=1:17
if any(strcmp(D(:),[EEG.chanlocs(i).labels]))
msgbox(sprintf('i is: %d',i));
else
msgbox(sprintf('Error'));
end
end
But it does not work and it returns weird things... I am not entirely sure what to try...
Can anybody help? Any help would be greatly appreciated!!
Thanks.
Edited:
The following code shows how I obtain D. I give the user 3 prompt windows to input certain data. I then store the inputs from each of these in "data" or "data2" or "data3" and then I put all of them together in D.
uiwait(msgbox(sprintf('Please enter your new references for each electrode.\nFor FP1, FP2, O1 and O2 provide two references.')));
prompt = {'Fp1','F7','T3','T5','O1'};
prompt2 = {'FP2','F8','T4','T6','O2'};
prompt3 = {'C3','CP3','Cz','CPz','C4','CP4'};
dlg_title = 'Input references';
num_lines = 1;
%def = {'20','hsv'};
answer = inputdlg(prompt,dlg_title,num_lines );
answer2 = inputdlg(prompt2,dlg_title,num_lines );
answer3 = inputdlg(prompt3,dlg_title,num_lines );
for i=1:5
data(i,:) = answer(i,:);
data2(i,:) = answer2(i,:);
end
for i=1:6
data3(i,:) = answer3(i,:);
end
D(1:5)=data(:);
D(6:10)=data2(:);
D(11:16)=data3(:);
D=D';
EDIT: I figured out the problem. claim was listed as a cell class. Used cell2mat to convert it to char, and the code worked. Thank you, everybody!
I have a string variable set to a file pathway/location. I would like to use this variable as the input to the xlsread function, but Matlab tells me that xlsread cannot take a variable input. I'm having lots of trouble figuring whether a workaround is even possible. Can someone help me out?
function C = claimReader()
inp = csv2struct(['C:\Documents and Settings\nkulczy\My Documents\085 Starry Sky\','Starry_Sky_inputs_vert.csv']);
inputTitles = [{'Output_Dir'};{'Claimz'};{'Prodz'};{'Fault_Locations'};{'Fault_Type'};{'Primary_Failed_Part'};{'Part_Group'};{'Selected_SEAG'};{'Change_Point'};{'Date_Compile'};{'Minimum_Date'}];
claim = inp.(cell2mat(inputTitles(2))); %returns a file path/location string
C = csv2struct(claim);
end
function Out = csv2struct(filename)
%% read xls file with a single header row
[~, ~, raw] = xlsread(filename);
[~ , ~, ext] = fileparts(filename);
if ~strcmpi(ext, '.csv') %convert non .csv files to .csv, so blanks stay blank
filename=[pwd,'tempcsv',datestr(now,'yymmddHHMMSSFFF'),'.csv'];
xlswrite(filename,raw);
[~ , ~, raw] = xlsread(filename);
delete(filename);
end
if size(raw,1)==11 && size(raw,2)==2 %transpose SS inputs (must match dimensions of input matrix EXACTLY!!!)
raw = raw';
end
nRow = size(raw,1);
nCol = size(raw,2);
header = raw(1,:);
raw(1,:) = [];
end
Use the syntax as following and there shouldn't be any problems:
pathname = 'c:\...\filename.xlsx';
A = xlsread(pathname);
Edit: regarding your code:
I can't see where you define filename - you should pass claim (it contains the desired path?) to the xlsread-function.
Probably you get a cell with chars. So your input needs to be claim{1}
Check the documentation of xlsread, the first output (yourNums) will only return the numerical values in the sheet. txt will only return text. rawData will return the raw data in the sheet.
flNm = 'c:\myFolder\myFile.xlsx';
[yourNums, txt, rawData] = xlsread(flNm);
Update after TS:
claim is a cell array. So you need to pass claim{1} in order to let it be a string.
I would like to read in a CSV file in as a 2D array and then return it back to a CSV file.
Let's say that this is my CSV file. It is an excel file and the | implies the adjacent cell:
family | type
Doctor | Pediatrics
Engineer | Chemical
From what I understand, there are no arrays on applescript, just lists and records. If it would be better to do this with a XLSX file, please let me know.
Nigel's CSV-to-list converter is the best I have seen ...
http://macscripter.net/viewtopic.php?pid=125444#p125444
For your example, use these settings:
set csvText to "family | type
Doctor | Pediatrics
Engineer | Chemical"
csvToList(csvText, {separator:"|"}, {trimming:true})
v2
set csvText to read "/Users/user1385816/Desktop/yourfile.csv"
csvToList(csvText, {}, {trimming:true})
An array is just a list in applescript, so you want a 2d array or a list-of-lists in applescript-speak. If you understand applescript's text item delimiters then your task is just simple manipulation to convert strings into lists and vice versa. So I wrote you a couple handlers to make the task easy for you; textToTwoDArray() and twoDArrayToText(). This first example shows how to convert your string into a list-of-lists using textToTwoDArray().
NOTE: you have to be careful of the line endings in a text file because they can be either a carriage return (character id 13) or a line feed (character id 10). You can see I used character id 10 in my code but if you aren't getting the proper results try "13".
set fileText to "family | type
Doctor | Pediatrics
Engineer | Chemical"
textToTwoDArray(fileText, character id 10, " | ")
on textToTwoDArray(theText, mainDelimiter, secondaryDelimiter)
set {tids, text item delimiters} to {text item delimiters, mainDelimiter}
set firstArray to text items of theText
set text item delimiters to secondaryDelimiter
set twoDArray to {}
repeat with anItem in firstArray
set end of twoDArray to text items of anItem
end repeat
set text item delimiters to tids
return twoDArray
end textToTwoDArray
And here's how to convert a list-of-lists back into your string using twoDArrayToText().
set twoDArray to {{"family", "type"}, {"Doctor", "Pediatrics"}, {"Engineer", "Chemical"}}
twoDArrayToText(twoDArray, character id 10, " | ")
on twoDArrayToText(theArray, mainDelimiter, secondaryDelimiter)
set {tids, text item delimiters} to {text item delimiters, secondaryDelimiter}
set t to ""
repeat with anItem in theArray
set t to t & (anItem as text) & mainDelimiter
end repeat
set text item delimiters to tids
return (text 1 thru -2 of t)
end twoDArrayToText
So now all you have to do is figure out how to read and write to a text file with applescript. Good luck ;)
If your question is just about modeling your CSV data in AppleScript, the solution is to use a list of records like this:
set csvData to {{family:"Doctor", type:"Engineer"}, {family:"Engineer", type:"Chemical"}}
you can then read that out again inside a repeat with aRow in csvData loop.
A technical note: AppleScript lists are implemented as vectors, meaning they are ordered and can be accessed by numerical index (beginning at index 1) – they behave much like an array in most other languages.