Separating Data in Excel - excel-formula

I receive data which is numbered consecutively but under each number there is zero, 1 , 2 or 3 pieces of information before the next number. I need to separate the data so that the numbers are evenly spaced!
Any help would be greatlyfully received - I should have done Excel at University but that was decades ago!
Thankyou,
Graeme
Hi Robert,As a Australian new user I am not allowed to insert images! Hence imagine each comma as separating cells and a dash as an empty Excel cell with the first row what I initially receive. The "g,h" etc are sentences. The 2nd row is what I would like to achieve. Unfortunately it wont format to show the cells going down not across so it has to be across here as it would in Excel or an inserted image! Thanks!
Receive 1,g,h,2,k,3,a,c,v,4,5,r,t
Require 1,g,h,-,2,k,-,-,3,a,c,v,4,-,-,-,5,r,t,-,
Hence if I received 3 pieces of information for each "number" (client) the numbers would automatically be evenly spaced but this unfortunately does not occur!

Graeme, let me know if you can create VBA Macro's based on an example.
I just wrote one that does the job, although being far form elegant.
<-----------CODE START--------->
Sub uniformdata()
ReceiveCol = 1 'Column where received data starts
ReceiveRow = 1 'Row where where received data starts
PublishCol = 1 'Column where Published data starts
PublishRow = 2 'Column where Published data starts
Do Until Cells(ReceiveRow, ReceiveCol).Value = ""
For counter = 1 To 4
If counter = 1 Then
Cells(PublishRow, PublishCol).Value = Cells(ReceiveRow, ReceiveCol).Value
ReceiveCol = ReceiveCol + 1
Else
If IsNumeric(Cells(ReceiveRow, ReceiveCol).Value) Then
Cells(PublishRow, PublishCol).Value = "-"
Else
Cells(PublishRow, PublishCol).Value = Cells(ReceiveRow, ReceiveCol).Value
ReceiveCol = ReceiveCol + 1
End If
End If
PublishCol = PublishCol + 1
Next
Loop
End Sub
<---------CODE END--------->
What it does is to go through your list from left to right until it finds an empty cell. Inside it constantly runs a loop for 4 times. On the first pass it assumes that your number is there, and immediately writes it. On the other 3 passes, it checks if the next received cell is a number or not. If it is a number it knows to fill in the gap with a dash, if it is not a number the character found is used.
Let me know if this solves your issue. In my example, it worked like a charm.
Regards,
Robert Ilbrink

Related

VBA Range.End(xlDown) stops at last visible row

I am doing a simple VBA script in Microsoft Excel which iterates a list of cars and a list of information about when the cars were refueled to provide an overview of how many kilometers each car is driving each month.
I make use of the Range.End property to calculate the number of rows with data and then loop through the indicies.
Set Data = Worksheets("Tankninger") ' Danish for refuellings
NumRows = Data.Range("A1", Data.Range("A1").End(xlDown)).Rows.Count
For x = 1 To NumRows
' Process data
Next
Everything seemed to be working fine, however I found that if someone applied a filter to e.g. the sheet with refuelling data - e.g. only showing data related to car A, then NumRows would be assigned the index of the last visible row.
Example: if the refuling sheet contains 100 records and the records related car A are located on row 50-60, then NumRows would be assigned the value 60 - resulting in my script ignoring the last 40 records.
Is there a way to make the Range.End property ignore any filter applied to sheet, or will I have to change the implementation to use a while-loop instead?
I ended up replacing the for-loop with a while-loop. This allowed me to access every cell regardless of any filtering applied to the sheets.
Set Data = Worksheets("Tankninger") ' Danish for refuellings
r = 2
While Not IsEmpty(Cars.Cells(r, 1).value)
' Process data
Wend
What you can do is add the following in your code to remove filters before you find the last row with data.
'Remove all filters
Worksheets("Sheet1").Activate
On Error Resume Next
ActiveSheet.ShowAllData

Need formula for excel, to subtract the number "9" to each number individually and

I want you to have some fun. I need something specific.
First i must explain what i do. I use a simple codification for product prices at retail store, because i dont want people know the real price for themselves. So i change the original numbers to another subtracting the number 9 for each number.
Normally I manually write down all the prices with this codification for every product.
So.. for example number 10 would be 89. (9-1 = 8) and (9-0 = 9)
Other examples:
$128 = 871
$75 = 24
$236 = 763
$9 = 0
Finally i put 2 number nines (9) at the beginning of the codified price also, to confuse people who might think that number could be the price.
So the examples i used before are like this:
99871 (means $128)
9924 (means $75)
99763 (means $236)
990 (means $9)
Remember that i need 2 (two) nines before the real price. The real prices never start with 0 so, the nines at the beginning exist only to confuse people.
Ok. So, now that you understand, here comes the 2nd part.
I have an excel whith hundreds of my products added, with prices, description, etc. And i decided it is time to use a printer and start to print this information from excel. I have a software to do that, but first i need to have the codified prices in the excel also.
The fun part begins when i want to convert the real prices that are already written in my excel document into a new column AUTOMATICALLY. So that way i donĀ“t have to type again all the prices in codified form for the old and new items i add in the future.
Can someone help me with this? Is it even possible?
I tried with =A1-9999 but, it works well with 2 character number only. Because if the real price is 5, i will get 3 nines: 9994(code). And if the price is 234 i will get only 1 nine 9765(code). And it is a condition i need to have the TWO nines at first.
Thank you very much in advanced!
Though you have requested for formula , I am suggesting VBA program which seems to me very convenient.
You have to open VBE and insert a module and copy the program. Change the code lines wherever indicated to suit your requirements for sheets etc.
Sub NumberCode()
Dim c As Range
Dim LR As Integer
Dim numProbs As Long
Dim sht As Worksheet
Dim s As Integer
Dim v As Long
Dim v1 As Long
Set sht = Worksheets("Sheet1") ' change as per yr requirement
numProbs = 0
LR = sht.Cells(Rows.Count, "A").End(xlUp).Row
For Each c In sht.Range("A1:A" & LR).Cells
s = Len(c)
v = c.Value
v1 = 99
For s = 1 To Len(c)
v1 = v1 & (9 - Mid(c, s, 1))
Next
c.Offset(0, 1).Value = v1
v1 = 99
numProbs = numProbs + 1
Next
MsgBox "Number coding finished"
End Sub
Sample sheet of results is appended below.
I will be using helper cells but you could dump it all into one cell if you want since you are only dealing with 4 characters.
For the purpose of this example, I am assuming your original price list starts in B11.
=IFERROR(9-MID($B11,COLUMN(A1),1),"")
Place that in D11 and copy to the right three more times so you have it from D11 to G11. That formula strips off 1 character from your price and subtracts that character from 9. When you go the next column it repeats itself. If you do not have that many characters, it will return "".
In C11 you will build your number based on the adjacent 4 columns using this formula:
="99"&D11&E11&F11&G11
It places 99 in front then adds the numbers from the adjacent 4 columns.
Select cells C11 to G11 and copy and paste downward beside your data column as far as you need to go.
An alternate more concise method would be:
=REPT(9,LEN(B11)+2)-B11
Perhaps I'm missing something, though simply:
=REPT(9,2+LEN(A1))-A1
seems good to me.
Regards

My for loop is too complex - Excel VBA

I'm still writing a program in Excel VBA, and I've been stuck on a specific problem for hours. I'm trying to determine if someone is available on a specific day, but the information I'm given is for when they aren't available.
So I'm trying to write a series of for loops to compare all of this information and put it into Excel. I'm facing the issue, though, of the fact that it's quite complex:
With ActiveSheet
' Check the ID_Array and Date_Array to see if any names match
For DateIndex = 0 To MinLimit
For IDIndex = 0 To ID_Number
'If (ID_Array(IDIndex, 0) = Date_Array(DateIndex, 0)) Then
' We're going to use our column not only as a match check, but as our way of ending the cycle
For colCounter = 2 To 6
' If the date in the doc and the date in the array match, continue
If (.Cells(1, colCounter).Text = Date_Array(DateIndex, 1)) Then
For rowCounter = 2 To 11
' If the time slot in this row matches up with the time slot in the array, and the name also matches up, mark the name to be unused in this row
If (.Cells(rowCounter, 1).Text = Date_Array(DateIndex, 2)) Then
If (ID_Array(IDIndex, 0) = Date_Array(DateIndex, 0)) Then
ID_Array(IDIndex, 3) = "1"
End If
End If
' If the name has not been flagged as 1, write it down in this row
If (ID_Array(IDIndex, 3) <> "1") Then
supahotstring = ", " + ID_Array(IDIndex, 1) + " " + ID_Array(IDIndex, 2)
.Cells(rowCounter, colCounter).Value = .Cells(rowCounter, colCounter).Text + supahotstring
End If
' If the name HAS been flagged as 1, unflag it for the next row, since it might need to be written there
If (ID_Array(IDIndex, 3) = "1") Then
ID_Array(IDIndex, 3) = "0"
End If
' Now that all names can be checked for availability again, move on to the next row in this column
Next
End If
Next
'End If
Next
Next
End With
Above is the series of for loops I'm using. for reference, I use SQL to draw in the data, so everything is organized by records.
Since the possible available dates are fixed, I use the values I have set up in my Excel doc as a comparison to the dates people have put in. Basically, if someone has marked a specific timeslot on a specific day, I want to flag the record with that name as "1" so that it doesn't get marked down in that row. Then, I see if the current name is marked as "1", apply the appropriate actions, unmark it as "1" so that it can be checked again later.
However, when I run the program, a variety of problems occur: sometimes, the program will freeze up and I'll be forced to end task (I save quite often these days). Other times, when I write, it will simply write the same names in the same order in every box.
I feel like this should be a relatively easy problem to fix, but at this point I need a second opinion. I need to talk it over with someone here who's willing to look at it, and perhaps even find a way to do this without using four for loops.
It's a fairly complex program, and if you need more code for reference then I'm willing to provide it. I've tried to comment this code enough that it's fairly easy to understand. I really appreciate any help you can give.
EDIT: I cannot provide an image of expected output, but I can describe it. Imagine John Doe is going to be available on the first day, after 9:00AM. The program simply writes his name, along with every else's names, eleven time in each box.

Loop through a combination of numbers

I am trying to think of a way to loop through a number of combinations making sure that I go through each available combination without repeat. Let me explain. I have a set of numbers, for example
20,000
25,000
27,000
29,000
and I would like to alter this set of numbers via a loop and copy the new numbers into a different sheet so that my formulas on that sheet can calculate whatever I need them to calculate. For example, the first couple of iterations might look something like this:
1st
20,000 x 1.001
25,000 x 1
27,000 x 1
29,000 x 1
2nd
20,002 x 1.001
25,000 x 1.001
27,000 x 1
29,000 x 1
The first row of numbers should never exceed the second. So 20,000 should only go as high as 25,000.
I was able to set up a system whereby I set up a matrix and then loop through a random set of combinations using =rand() however this does not ensure I hit every combination and also repeats combinations.
Can anyone explain the math behind this and also how I would use a loop to accomplish my goal?
Thank you!
Try starting with smaller numbers.
See if this works for you.
Sub looper()
'First Array
Dim myArray(9) As Double
For i = 1 To 10
myArray(i - 1) = i
Next i
'Second Array
Dim myOtherArray(9) As Double
For i = 1 To 10
myOtherArray(i - 1) = i
Next i
'Loop through each one
For Each slot In myArray
For Each otherSlot In myOtherArray
Debug.Print (slot & " * " & otherSlot & " = " & slot * otherSlot)
Next otherSlot
Next slot
End Sub
GD user1813558,
Your question contains too little detail and is too broadly scoped to be able to provide a accurate answer.
Are your numbers arbitrary (i.e. the ones you provided are 'just'
samples) or will they be fixed as per your indicated numbers ?
Will there always be only 4 numbers ?
Is the distribution of your startnumbers (i.e. their difference
value) always as per your indication 0, +5000, +2000, +2000
Will the results of all 'loops' (or iterations) need to be copied to
a different sheet ? (i.e looping from 20.000 to 25.000 by increments
of 1.001 would require about 223 iterations, and subsequently sheets,
before the result starts exceeding 25.000 ?)
Does a new sheet need to be created for each iteration result or are they
existent or will the result be copied to the same sheet for every iteration ?
In short, please provide a more accurate question.

Reading and Combining Excel Time Series in Matlab- Maintaining Order

I have the following code to read off time series data (contained in sheets 5 to 19 in an excel workbook). Each worksheet is titled "TS" followed by the number of the time series. The process works fine apart from one thing- when I study the returns I find that all the time series are shifted along by 5. i.e. TS 6 becomes the 11th column in the "returns" data and TS 19 becomes the 5th column, TS 15 becomes the 1st column etc. I need them to be in the same order that they are read- such that TS 1 is in the 1st column, TS 2 in the 2nd etc.
This is a problem because I read off the titles of the worksheets ("AssetList") which maintain their actual order throughout subsequent codes. Therefore when I recombine the titles and the returns I find that they do not match. This complicates further manipulation when, for example column 4 is titled "TS 4" but actually contains the data of TS 18.
Is there something in this code that I have wrong?
XL='TimeSeries.xlsx';
formatIn = 'dd/mm/yyyy';
formatOut = 'mmm-dd-yyyy';
Bounds=3;
[Bounds,~] = xlsread(XL,Bounds);
% Determine the number of worksheets in the xls-file:
FirstSheet=5;
[~,AssetList] = xlsfinfo(XL);
lngth=size(AssetList,2);
AssetList(:,1:FirstSheet-1)=[];
% Loop through the number of sheets and RETRIEVE VALUES
merge_count = 1;
for I=FirstSheet:lngth
[FundValues, ~, FundSheet] = xlsread(XL,I);
% EXTRACT DATES AND DATA AND COMBINE
% (TO REMOVE UNNECCESSARY TEXT IN ROWS 1 TO 4)
Fund_dates_data = FundSheet(4:end,1:2);
FundDates = cellstr(datestr(datevec(Fund_dates_data(:,1),...
formatIn),formatOut));
FundData = cell2mat(Fund_dates_data(:,2));
% CREATE TIME SERIES FOR EACH FUND
Fundts{I}=fints(FundDates,FundData,['Fund',num2str(I)]);
if merge_count == 2
Port = merge(Fundts{I-1},Fundts{I},'DateSetMethod','Intersection');
end
if merge_count > 2
Port = merge(Port,Fundts{I},'DateSetMethod','Intersection');
end
merge_count = merge_count + 1;
end
% ANALYSE PORTFOLIO
Returns=tick2ret(Port);
q = Portfolio;
q = q.estimateAssetMoments(Returns)
[qassetmean, qassetcovar] = q.getAssetMoments
This is probably due to merge. By default, it sorts columns alphabetically. Unfortunately, as your naming pattern is "FundN", this means that, for example, Fund10 will normally be sorted before Fund9. So as you're looping over I from 5 to 19, you will have Fund10, through Fund19, followed by Fund4 through Fund9.
One way of solving this would to be always use zero padding (Fund01, Fund02, etc) so that alphabetical order and numerical order are the same. Alternatively, force it to stay in the order you read/merge the data by setting SortColumns to 0:
Port = merge(Port,Fundts{I},'DateSetMethod','Intersection','SortColumns',0);

Resources