Changing the order of columns in a CSV file in VB.NET - vb.net

I have a CSV files output from a software without headers,
I need to change the order of columns based on a config file
initial-column Final-Column
1 5
2 3
3 1
Any ideas how to go about this?

There is very very little to go on, such as how the config file works and what the data looks like.
Note that using the layout of {1, 5, 2, 3, 3, 1} you arent just reordering the columns, that drops one (4) and duplicates columns 1 and 3.
Using some fake random data left over from this answer, this reads it in, then writes it back out in a a different order. You will have to modify it to take the config file into consideration.
Sample data:
Ndxn fegy n, 105, Imaypfrtzghkh, -1, red, 1501
Mfyze, 1301, Kob dlfqcqtkoccxwbd, 0, blue, 704
Xe fnzeifvpha, 328, Mnarhrlselxhcyby hq, -1, red, 1903
Dim csvFile As String = "C:\Temp\mysqlbatch.csv"
Dim lines = File.ReadAllLines(csvFile)
Dim outFile As String = "C:\Temp\mysqlbatch2.csv"
Dim data As String()
Dim format As String = "{0}, {4}, {1}, {2}, {2}, {0}"
Using fs As New StreamWriter(outFile, False)
For Each s As String In lines
' not the best way to split a CSV,
' no OP data to know if it will work
data = s.Split(","c)
' specifiy the columns to write in
' the order desired
fs.WriteLine(String.Format(format,
data(0),
data(1),
data(2),
data(3),
data(4),
data(5)
)
)
Next
End Using
This approach uses the format string and placeholder ({N}) to control the order. The placeholders and array elements are all zero based, so {1, 5, 2, 3, 3, 1} becomes {0, 4, 1, 2, 2, 0}. Your config file contents could simply be a collection of these format strings. Note that you can have more args to String.Format() than there are placeholders but not fewer.
Output:
Ndxn fegy n, red, 105, Imaypfrtzghkh, Imaypfrtzghkh, Ndxn fegy n
Mfyze, blue, 1301, Kob dlfqcqtkoccxwbd, Kob dlfqcqtkoccxwbd, Mfyze
Xe fnzeifvpha, red, 328, Mnarhrlselxhcyby hq, Mnarhrlselxhcyby hq, Xe fnzeifvpha
Splitting the incoming data on the comma (s.Split(","c)) will work in many cases, but not all. If the data contains commas (as in some currencies "1,23") it will fail. In this case the seperator char is usually ";" instead, but the data can have commons for other reasons ("Jan 22, 2016" or "garden hose, green"). The data may have to be split differently.
Note: All the OPs previous posts are vba related. The title includes VB.NET and is tagged vb.net, so this is a VB.NET answer

Related

How to remove single occurrence of an element from array in PostgreSQL

I have a table (attributes) as defined
Id, type, value, tokenIds, contract, count, createdAt, updatedAt.
Here: tokenIds is text array and contains comma seperated non-unique ids. i.e: 1,2,3,3,4,4,5.
Its quite straightforward to add more ids in, but in a scenario i have to revert this operation.
Allow me to walk you through a scenario.
NEW = {1, 5, 0x01, headscarf, blue ribbon, {1}, , 1}
NEW = {1, 5, 0x01, headscarf, red ribbon, {2,3}, 2}
NEW = {1, 5, 0x01, headscarf, blue ribbon, {1,1,2}, 2} is REVERTED
REVERT = {1, 5, 0x01, headscarf, blue ribbon, {1}, 1}
I want to delete a list of items from stored array in db in a way that it only deletes only one occurrence of it.
(I tried my best to explain)
I tried ‘array_remove’ it removes all the occurrences, I tried some other methods but they are preventing duplication.
Data set: [1,2,3,3,2,3,4,2,6]
If i want to remove (2,3)
It remove just one occurrence. So, expected output is:
[1,2,3,3,4,2,6]
A first attempt:
select
string_to_array(
regexp_replace(
array_to_string(
array[1,2,3,3,2,3,4,2,6], ','),
'2,3,', ''
),
',')::integer[];
string_to_array
-----------------
{1,3,2,3,4,2,6}

Exporting amounts using space as '000 delimiter

I would like all amounts exported to Excel to use space as '000 delimiter and ',' for decimal. E.g: "3 257 132,54" (common number format in Europe)
I tried to adapt the example provided on xlsxwriter.readthedocs.io :
format1 = workbook.add_format({'num_format': '#,##0.00'})
As follows
format1 = workbook.add_format({'num_format': '# ##0,00'})
I am using the code from the xlsxwriter doc. I just modified the '000 delimiter and the decimal point:
# Add some cell formats.
format1 = workbook.add_format({'num_format': '#,##0.00'})
# Set the column width and format.
worksheet.set_column('B:B', 18, format1)
I obtain a very surprising result. The example provided above will appear,in Excel, as: 3257 132,54.
Almost good, but the '000 separator is only used once for thousands, but not for millions or billions. (nb: the comma as decimal separator works fine)
Is there a trick I missed?
You just need to use whatever number format that you would use in Excel for this. Probably something like ### ### ###.00 (although it doesn't have a comma for a decimal):
import xlsxwriter
workbook = xlsxwriter.Workbook('test.xlsx')
worksheet = workbook.add_worksheet()
format1 = workbook.add_format({'num_format': '### ### ###.00'})
worksheet.set_column('B:B', 18, format1)
worksheet.write(0, 1, 123.123)
worksheet.write(1, 1, 1234.123)
worksheet.write(2, 1, 12345.123)
worksheet.write(3, 1, 123456.123)
worksheet.write(4, 1, 1234567.123)
worksheet.write(5, 1, 12345678.123)
workbook.close()
Output:
You can find the exact number format you need by setting it in Excel and then checking what it is in the custom section of the number format dialog.

Anyone feel like a Gematria numeric challenge in EXCEL VBA?

To explain: I’m in EXCEL and need a genius formula in VBA, where each letter in the alphabet (except j) is given a SPECIFIC numeric value (as listed below), so that as you type LETTERS in one cell, the SUM OF THE NUMERIC VALUES appear in the cell next to it.
a=1 b=2 c=600 d=4 e=5 f=500 g=3 h=8 i=10
k=20 l=30 m=40 n=50 o=70 p=80 q=9 r=100 s=200
t=300 u=400 v=200 w=800 x=60 y=700 z=7
(Note: It should also apply to CAPS and a space should count zero)
e.g: If I type the words lady asks help in cell A1, the value 1279 should appear in cell B1
(Seeing that l=30, a=1, d=4, y=700, a=1, s=200, k=20, s=200, h=8, e=5, l=30, p=80)
The same formula should apply to the rest of Columns A and B.
In case it’s important, I need it for Greek Gematria. As I type “abc” on the keyboard, the Greek letters “αβχ” appear on the screen (by use of the Tyndale House keyboard code). Each Greek letter has a set numeric value, confirming numeric patterns found in Greek Bible Texts.
I’ve found fixed programs using Greek Gematria (e.g. DAVAR4), but none are editable text and I don’t know how to get into their ‘brains’ to transfer it to EXCEL. Frankly, I’m really clueless when it comes to programming and don’t even know if what I’m asking is possible. Local programmers referred me to Stack Overflow, so ANY help or directive would be much appreciated!
I looked at this question & answer, asked Jul 7 '14 by data_garden, but alas, I’m a dummy!
Please say if any more info is needed. Thanks
You're in luck. There are votes for this to be closed as you've made no apparent effort to write the code yourself. I've written something similar myself recently so all that was needed was to replace the array with your scoring system and it is below:
Function gem(txt As String) As Long
gem = 0
Dim i As Long, c As Integer
Dim arr()
arr = Array(0, 1, 2, 600, 4, 5, 500, 3, 8, 10, 0, 20, 30, 40, 50, 70, 80, 9, 100, 200, 300, 400, 200, 800, 60, 700, 7)
For i = 1 To Len(txt)
c = Asc(Mid(UCase(txt), i, 1)) - 64
If c > 0 And c <= 26 Then gem = gem + arr(c)
Next
End Function

Fortran runtime error while reading a file: "Bad repeat count"

I'm trying to read an input file with fortran but I get the following error at runtime:
At line 118 of file prog.f90 (unit = 53, file = 'data.dat')
Fortran runtime error: Bad repeat count in item 1 of list input
The data file is the following
3, 5, 3 %comment
%%%%%%%%%%%%%%
1d0, 0d0, 0d0 % comment
0d0, 0d0, 1d0
%%%%%%%%%%%%%%
1, 1, identity, 1, 1 %comment
1, 2, sigmax, 2, 2
2, 3, sigmax, 2, 2
1, 3, sigmaz, 1, 3
3, 3, identity, 1, 1
%%%%%%%%%%%%%%
0, 0 %comment
and the interesting part of prog.f90 is
COMPLEX(KIND(1D0)), DIMENSION(:), ALLOCATABLE:: H1, H2
INTEGER :: i,A,B,C
CHARACTER(50) :: GHOST
OPEN(UNIT=53,file='data.dat',status='old')
READ(53,*) A,B,C
READ(53,*) GHOST
ALLOCATE (H1(A),H2(A))
READ(53,*) (H1(i), i=1,A)
READ(53,*) (H2(i), i=1,A)
where the 118th line is READ(53,*) (H1(i), i=1,A). I tryed also with an explicit do loop but with the same result.
I haven't tested this, but I'd expect
READ(53,*) (H1(i), i=1,A)
to try to read 3 complex numbers. It gets fed the line
1d0, 0d0, 0d0 % comment
from which it gets 1½ complex numbers and then barfs on the % sign, misinterpreting it as a syntactically invalid repeat count.
I'd suggest providing 3 complex numbers in the file when that read statement is executed.
The numbers are dimensioned complex, while in fortran complex numbers should be in the file with parenthesis as:
( realpart , imaginarypart ) ( realpart , imaginarypart )
I really don't know what the standards say regarding the input form you have presented, but after some testing gfortran throws that Bad repeat count error regardless of the % comment. It throws that error even with four or more comma separated reals on the line.
Now ifort on the other hand reads the line just the way you have it -- but watch out -- it reads each of the comma separated values as the real part of your complex variable, setting the imaginary part to zero. ( that is it only uses the first two values on each line and discards the third )
You will really need to study the code to make sure you understand what was intended to sort out how to fix this. If the later (ifort) behavior is the intention one simple fix would be to declare a couple of reals. Read into the reals, then assign those to your complex variables.

How to load 2D array from a text(csv) file into Octave?

Consider the following text(csv) file:
1, Some text
2, More text
3, Text with comma, more text
How to load the data into a 2D array in Octave? The number can go into the first column, and all text to the right of the first comma (including other commas) goes into the second text column.
If necessary, I can replace the first comma with a different delimiter character.
AFAIK you cannot put stings of different size into an array. You need to create a so called cell array.
A possible way to read the data from your question stored in a file Test.txt into a cell array is
t1 = textread("Test.txt", "%s", "delimiter", "\n");
for i = 1:length(t1)
j = findstr(t1{i}, ",")(1);
T{i,1} = t1{i}(1:j - 1);
T{i,2} = strtrim(t1{i}(j + 1:end));
end
Now
T{3,1} gives you 3 and
T{3,2} gives you Text with comma, more text.
After many long hours of searching and debugging, here's how I got it to work on Octave 3.2.4. Using | as the delimiter (instead of comma).
The data file now looks like:
1|Some text
2|More text
3|Text with comma, more text
Here's how to call it: data = load_data('data/data_file.csv', NUMBER_OF_LINES);
Limitation: You need to know how many lines you want to get. If you want to get all, then you will need to write a function to count the number of lines in the file in order to initialize the cell_array. It's all very clunky and primitive. So much for "high level languages like Octave".
Note: After the unpleasant exercise of getting this to work, it seems that Octave is not very useful unless you enjoy wasting your time writing code to do the simplest things. Better choices seems to be R, Python, or C#/Java with a Machine Learning or Matrix library.
function all_messages = load_data(filename, NUMBER_OF_LINES)
fid = fopen(filename, "r");
all_messages = cell (NUMBER_OF_LINES, 2 );
counter = 1;
line = fgetl(fid);
while line != -1
separator_index = index(line, '|');
all_messages {counter, 1} = substr(line, 1, separator_index - 1); % Up to the separator
all_messages {counter, 2} = substr(line, separator_index + 1, length(line) - separator_index); % After the separator
counter++;
line = fgetl(fid);
endwhile
fprintf("Processed %i lines.\n", counter -1);
fclose(fid);
end