Well i am completely stuck in reading an excel sheet(beginner with python)....I have 3 columns in an excel sheet say (A, B and C) with n number of rows in each of them ....so how can i possibly create a loop which iterates over all the rows till it reaches the end and write the content in a text file(.txt)....number of rows being same for all 3 columns....help please
code I'm using to open up the excel sheet is :
import xlrd
workbook = xlrd.open_workbook('Book1.xlsx')
worksheet = workbook.sheet_by_name('Sheet1')
Code used:
num_rows = worksheet.nrows - 1
num_cells = worksheet.ncols - 1
curr_row = -1
while curr_row < num_rows:
curr_row += 1
row = worksheet.row(curr_row)
curr_cell = -1
while curr_cell < num_cells:
curr_cell += 1
cell_value = worksheet.cell_value(curr_row, curr_cell)
print (cell_value)
Code follows your code will be:
textfile=open(filenameOfTextFile, 'w')
rows=sheet.nrows
for row in range(rows):
textfile.write(sheet.cell(row,0).value + "," + sheet.cell(row,1).value + "," + sheet.cell(row,2).value + "\n")
Related
I cannot extract the postal/zip code of a given address cell that comes like this :
"108, avenue du Grand Sud 37 170 CHAMBRAY les TOURS".
I have used :
=RECHERCHE(9^9;--("0"&STXT(A2;MIN(CHERCHE({0.1.2.3.4.5.6.7.8.9};A2&"0 123456789"));LIGNE($1:$100))))
Which sometimes works, sometimes not depending on the street number starting the address (here "108,").
The problem is the space of the pattern "37 170". I would like to remove the blank space in the pattern. Is there a regex way to search this pattern "## ###", and then to remove this poisonous blank space?
Thank you for your tricks.
I have tried this piece of code :
Function toto(r, Optional u = 0)
Application.Volatile
Dim i%, j%, adr$, cp$, loca$, x
x = Split(r)
For i = 0 To UBound(x)
If x(i) Like "#####" Then Exit For
Next
If i > UBound(x) Then
adr = r.Value 'facultatif
Else
cp = x(i)
For j = 0 To i - 1: adr = adr & x(j) & " ": Next
adr = Left$(adr, Len(adr) + (Len(adr) > 1))
For j = i + 1 To UBound(x): loca = loca & x(j) & " ": Next
loca = Left$(loca, Len(loca) + (Len(loca) > 1))
End If
x = Array(adr, cp, loca)
If 0 < u And u < 4 Then toto = x(u - 1) Else toto = x
End Function
The above code works fine for splitting addresses including street number, zip code, and city name. But it does not work when the zip code is ## ### = 2 digit integer - space - 3 digit integer.
Edit: 01 June 2021
Since it seems my question is not clear enough, let's rephrase :
Given an Excel worksheet containing in each cell of column A, from saying A1 down to A10000, complete addresses like this one :
"2 rue Rene cassin Centre Commercial Châlon 2 Sud 71 100 CHALON SUR SAONE"
or this one :
"15, Rue Emile Schwoerer 68 000 COLMAR"
Where "71 100" and "68 000" are a zip code in incorrect format because of the extra space between the 2 first digits and 3 last digits.
I need to split the Ai cell content in order to obtain :
in cell Bi : the text (street, etc.) placed left before the 2 first digits of the "wrong" zip code,
in cell Ci : the zip code with its correct format ("71100" and not "71 100"),
in cell Di : the text (city name) after the zip code.
It's a kind of left and right extraction around the zip code.
The above code that I have posted does not work.
In order to obtain the correct zip code format, I have tried the regex following function :
Function FindReplaceRegex(rng As Range, reg_exp As String, replace As String)
Set myRegExp = New RegExp
myRegExp.IgnoreCase = False
myRegExp.Global = True
myRegExp.Pattern = reg_exp
FindReplaceRegex = myRegExp.replace(rng.Value, replace)
End Function
But I am unable to determine the correct regular expression pattern to get rid of the space in the zip code.
PEH gave me the following pattern :
(.*)([0-9]{2} ?[0-9]{3})(.*)
When using the function, I have tried to define the replacement pattern by:
(.*)([0-9]{2}[0-9]{3})(.*)
But it would not work. Hope this will clarify my question.
Any idea is welcome. Thanks
If these input strings always have the same pattern, try:
=CONCAT(FILTERXML("<t><s>"&SUBSTITUTE(A1," ","</s><s>")&"</s></t>","//s[.*0=0]"))
Depending on your needs/edge-cases, you could add more xpath expressions.
If this is VBA, I have a fix for you (please forgive the crappy naming convention, I'm scribbling this down in work while waiting for SQL to refresh):
Sub test1()
a0 = Cells(1, 1) 'Get the text, in this case "108, avenue du Grand Sud 37 170 CHAMBRAY les TOURS"
aa = Replace(a0, ",", " ") 'Make all delimiters of same type, so removing commas, you may need to add more replace work here?
ab = Application.Trim(aa) 'Reduce all whitespace to single entries, i.e. " " rather than " "
ac = Split(ab, " ", -1) 'Now split by that single whitespace entry
Dim txt()
i2 = 0
lastIsNumeric = False
For i1 = 0 To UBound(ac) - 1 'Step through each entry in our "split" list
If IsNumeric(ac(i1)) = True And IsNumeric(ac(i1 + 1)) = True Then
'Two numbers back to back, join
ReDim Preserve txt(i2)
txt(i2) = ac(i1) + ac(i1 + 1)
i2 = i2 + 1
i1 = i1 + 1
Else
'Not two numbers back to back, don't join
ReDim Preserve txt(i2)
txt(i2) = ac(i1)
i2 = i2 + 1
End If
Next i1
If IsNumeric(ac(UBound(ac))) = False Then
'Need to add last entry to txt()
ReDim Preserve txt(UBound(txt) + 1)
txt(UBound(txt)) = ac(UBound(ac))
End If
End Sub
edit 2021-06-01:
The above will generate a list (txt) of all the entries within your address. You can then reassemble if you wish, or extract out the postcode only.
If you want it as a function, then it would be:
Public Function getPostcode(a0)
aa = Replace(a0, ",", " ")
ab = Application.Trim(aa)
ac = Split(ab, " ", -1)
Dim txt()
i2 = 0
lastIsNumeric = False
For i1 = 0 To UBound(ac) - 1
If IsNumeric(ac(i1)) = True And IsNumeric(ac(i1 + 1)) = True Then
'Two numbers back to back, join
ReDim Preserve txt(i2)
txt(i2) = ac(i1) + ac(i1 + 1)
i2 = i2 + 1
i1 = i1 + 1
Else
'Not two numbers back to back, don't join
ReDim Preserve txt(i2)
txt(i2) = ac(i1)
i2 = i2 + 1
End If
Next i1
If IsNumeric(ac(UBound(ac))) = False Then
'Need to add last entry to txt()
ReDim Preserve txt(UBound(txt) + 1)
txt(UBound(txt)) = ac(UBound(ac))
End If
'Re-assemble string for return
rtnTxt = ""
For i1 = 0 To UBound(txt)
rtnTxt = rtnTxt & " " & txt(i1)
Next i1
getPostcode = rtnTxt
End Function
I want to take input like this. Here 2 is number of test cases 4 is number of input in Array respectively.
Here is sample of input.
2
4
1 5 3 2
3
3 2 7
Is this what you're looking for?
test_cases = []
number_of_cases = input ('Enter the number of test cases : ')
for index in range (int (number_of_cases)) :
test_cases.append ([])
prompt = 'Enter the number of digits for test ' + str (index + 1) + ' : '
number_of_digits = input (prompt)
for count in range (int (number_of_digits)) :
prompt = 'Enter test case number ' + str (count + 1) + ' : '
test_cases[index].append (input (prompt))
print (test_cases)
I have a delimited array like this below:
BKR:::10-03:::2
BKR:::10-04:::1
BKR:::10-04:::4
BKR:::10-07:::7
BKR:::10-08:::6
BKR:::10-10:::2
BKR:::10-10:::2
BKR:::10-11:::3
CR:::10-04:::4
CR:::10-07:::2
CR:::10-07:::2
EL:::10-02:::4
EL:::10-03:::1
EL:::10-04:::2
EL:::10-07:::1
EL:::10-07:::2
EL:::10-07:::2
EL:::10-07:::2
EL:::10-07:::4
RL:::10-08:::6
I would like to reduce the rows where there are duplicate second columns (for e.g.,rows 2 and 3 have BKR 10-4, so, I want one row BKR 10-4 but add up 1 + 4 and show as BKR:::10-04:::5)
Finally, the array should like this:
BKR:::10-03:::2
BKR:::10-04:::5
BKR:::10-07:::7
BKR:::10-08:::6
BKR:::10-10:::4
BKR:::10-11:::3
CR:::10-04:::4
CR:::10-07:::4
EL:::10-02:::4
EL:::10-03:::1
EL:::10-04:::2
EL:::10-07:::11
RL:::10-08:::6
Thanks in advance.
Update
Here is what I attempted to code after I read the article that #Marcucciboy2 shared in his comments. I am, however, unable to retrieve that specific index of the matching key so that I could manipulate the value of they key.
For j = 0 To var2.Count - 1
If dict.Exists(JSONObj2("fields")("worklog")("worklogs")(j + 1)("author")("displayName") + ":" + Right(Left(JSONObj2("fields")("worklog")("worklogs")(j + 1)("updated"), 10), 5)) Then
For k = 0 To dict.Count - 1
MsgBox dict.Keys(k) + " and its item is " + dict.Items(k)
Next k
Else
dict.Add JSONObj2("fields")("worklog")("worklogs")(j + 1)("author")("displayName") + ":" + Right(Left(JSONObj2("fields")("worklog")("worklogs")(j + 1)("updated"), 10), 5), Left(JSONObj2("fields")("worklog")("worklogs")(j + 1)("timeSpent"), 1)
End If
Next j
it might be a basic question. I am a beginner.
When I am trying to import an excel file with 5 columns and row 1 as column header, and generating a function for doing the same, MATLAB is not generating 5 variable as per the column headers, but only one variable and that too with the default name, ans.
Kindly help.
Here is the code:
function [Date,Open,High,Low,Close] = importfile(workbookFile,sheetName,startRow,endRow)
% If no sheet is specified, read first sheet
if nargin == 1 || isempty(sheetName)
sheetName = 1;
end
% If row start and end points are not specified, define defaults
if nargin <= 3
startRow = 2;
endRow = 250;
end
%% Import the data, extracting spreadsheet dates in MATLAB serial date number format (datenum)
[~, ~, raw, dateNums] = xlsread(workbookFile, sheetName, sprintf('A%d:E%d',startRow(1),endRow(1)),'' , #convertSpreadsheetDates);
for block=2:length(startRow)
[~, ~, tmpRawBlock,tmpDateNumBlock] = xlsread(workbookFile, sheetName, sprintf('A%d:E%d',startRow(block),endRow(block)),'' , #convertSpreadsheetDates);
raw = [raw;tmpRawBlock]; %#ok<AGROW>
dateNums = [dateNums;tmpDateNumBlock]; %#ok<AGROW>
end
%% Replace date strings by MATLAB serial date numbers (datenum)
R = ~cellfun(#isequalwithequalnans,dateNums,raw) & cellfun('isclass',raw,'char'); % Find spreadsheet dates
raw(R) = dateNums(R);
%% Create output variable
data = reshape([raw{:}],size(raw));
%% Allocate imported array to column variable names
Date = data(:,1);
Open = data(:,2);
High = data(:,3);
Low = data(:,4);
Close = data(:,5);
Do [Date,Open,High,Low,Close] = importfile('filename.xlsx');
I have a list of products with the ID and the picture name. One entry per picture, instead of one entry per product and the pictures in columns as I need it. If the file had only a few entries, the manual procedure I guess it would be to cut all the picture names for the same product, paste (transpose) and remove the entries without names. But since the file has over 100,000 entries, does anyone know how to do this using VBA?
EXAMPLE:
What I have...
product_id; picture_name
1; picture1.jpg
1; picture2.jpg
1; picture3.jpg
2; picture4.jpg
3; picture5.jpg
3; picture6.jpg
What I need...
product_id; 1st_picture; 2nd_picture; 3rd_picture...
1; picture1.jpg; picture2.jpg; picture3.jpg
2; picture4.jpg
3; picture5.jpg; picture6.jpg
Thank so you much in advance for your help.
I guess this solves your problem
Compare two consecutive rows one by one
If two rows matches,Take the corresponding value in 2nd column of 2nd row put the value in next to 2nd column of 1st row and delete the 2nd row
If not matches skip the previous step and go for comparison of next two rows.
Here is the Code
Sub SortPics()
i = 2
Do
Flag = False
VarComp1 = Sheets("YourSheetName").Cells(i, 1).Value
VarComp2 = Sheets("YourSheetName").Cells(i + 1, 1).Value
If VarComp1 = VarComp2 And VarComp2 <> "" Then
Set VarSec1 = Sheets("YourSheetName").Cells(i, 2)
Set VarSec2 = Sheets("YourSheetName").Cells(i + 1, 2)
VarSec1.Offset(0, 1 + j).Value = VarSec2.Value
Sheets("YourSheetName").Cells(i + 1, 1).EntireRow.Delete
i = i - 1
Flag = True
End If
i = i + 1
If Flag = True Then
j = j + 1
Else
j = 0
End If
Loop While VarComp1 <> ""
End Sub