I am trying to create a stock screener through excel. First off, Excel may not be the best choice for stock screen creation, so I'm open to alternatives, but
1. I'm almost done, and
2. I have zero programming experience
So before I tell you my problem, here's what I've got so far (Working on the ROIC tab): https://jumpshare.com/v/OxlCrsMZa18tS9bB8N1S?b=D89mk1t3hPnWdxyYxL6p
What I can't do, and what would complete the screener, is make a query for every single cell. Now I think, although I don't KNOW, that it is possible to create a macro which starts a query, tells excel where to put the data (50 rows down from the previous input), and tells excel where to find what ticker to put in (one row down from previous ticker). The query making also has to repeat to the end of the tickers. (you may be thinking: "isn't the excel row limit approx. 1 million?" It is, and my solution to that is to put half the balance sheets from columns A:F, and the other half from H:M. You don't need to include that, though, I can figure it out.)
The query pulls company balance sheets from yahoo finance, and then imports the data to the Data sheet. Since the balance sheets are all formatted the same, it is easy to sort: each metric is 50 rows down from the previous search.
The reason I need to automate this query creation process is that there are approximately 25,000 stocks, and to make a screener, I need to analyze them all at the same time; each stock, therefore, needs its own query and own data.
I've tried recording a macro, but I just can't seem to get it to repeat, offset 50 rows every new data query, and offset 1 row every new ticker.
I would really appreciate the help; I am very new to excel, and I'm not entirely sure how possible it is to do what I'm asking. Thanks!
I can't help but think you'd be better off using a database (such as Microsoft Access) instead of Excel to store this amount of data. You could still run your calculations from a spreadsheet and query the data table in the Access database. It's a fun (and maddening!) journey to develop your own Excel application. Having said that...
What you need to study in VBA is looping. Start with a simple loop on a set of the ticker values in the column:
Option Explicit
Sub test()
Dim ticker As String
Dim companyTicker As Range
Dim allTickers As Range
Dim lastRow As Long
'---sets up a range containing all your ticker strings
Dim lngMaxRow As Long
lastRow = Sheets("ROIC").Range("B" & Rows.Count).End(xlUp).Row
'---during your development, force your ticker set to be shorter
lastRow = 10
Set allTickers = Range("B5:B" & lastRow)
'---now loop through all the companies and get the info for each one
For Each companyTicker In allTickers
ticker = companyTicker.Value
'--- build up the query to Yahoo Finance using the company ticker string
' copy the data from your query to the cells in your workbook
Debug.Print "ticker is " & ticker 'use a debug.print to check as you write the code
Next companyTicker 'get the next company ticker
End Sub
Related
I'm quite new to Stack Overflow and VBA, so forgive me.
For x = 1 To Rows
For y = 1 To rs.Fields.Count
Select Case rs.Fields(y - 1)
Case rs![begin_date], rs![end_date]
Z = CDate(rs.Fields(y - 1))
Case rs![deadline_date]
If rs![update_date] = "" Or IsNull(rs![update_date]) Then
Z = Calculate_deadline(rs![begin_date], rs![sla], _
rs![special_calendar])
Else
Z = Calculate_deadline(rs![update_date], rs![sla], _
rs![special_calendar])
End If
Case Else
Z = rs.Fields(y - 1)
End Select
table_list_object.HeaderRowRange.Cells(x + 1, y).Value = Z
Next y
rs.MoveNext
Next x
So, in a nutshell, I'm writing a VBA code in Access that executes a Query to gather the data about all the project dates, calculates its deadlines and write all that in an Excel table.
The function part calculates the deadline date.
The problem is, I write every data one by one, like this:
table_list_object.HeaderRowRange.Cells(x + 1, y).Value = z
That might take a while, and I'm pretty sure this does slow down a lot my macro, but every VBA tutorial I saw did like this.
And I'm a little skeptical about the Select Case thing... Is it better that way, or should I use If ... Else instead?
Anyways, this Recordset has 15.000 rows but it's taking hours to execute, and the first times I ran this code it took some minutes, only.
Oh, by the way, the Calculate_deadline also might be the problem, I know. But I wanna be sure about this part of my code first, just to not make this question too big and complex to explain.
Thanks!
Vitor, since you are new to VBA, I'd suggest that you consider another way to do this in Excel. Excel has a "Get Data" function that uses a technology called Power Query to pull data into Excel, manipulate it, and then save the manipulated data into a sheet in your Excel workbook. All of this using a point-and-click interface, rather than writing low-level VBA code.
See the following as an example:
https://www.youtube.com/watch?v=vchsUEHXvZo
This function is fairly easy to learn, and has common data manipulation functions, like filtering data, aggregating data, adding new calculated columns, transposing data, etc.
Just google "Power Query", and surf the videos and other resources out there.
I have a small query regarding automatic formula value calculation in excel.
In my project I will be having 200 questions and corresponding 200 answers( numerical values of 10,20 and 30). Those questions and answers are obtained from webpages and all the questions and answers are stored in my sql database. I will collect the answers that are posted in mysql database to excel with the help of mysql add-in.
My question is I have some formulas
given in my excel sheet ex:mean(C204), STDEV(C205), final risk( my own formula F209)
I want the formulas to automatically calculate the formula values whenever I import the
data from mysql. Is it possible in excel if not is there any alternative? Please help!
This is kind of a stab in the dark since I'm not at all familiar with the add in or how it operates. It seems odd that it would import data and not allow a application.calculate event to take place after import.
Perhaps... you can run the application.calculate method on worksheet change. In your VBE, double click the worksheet upon which the mysql data is dropped. Then add this code to that worksheet:
Private Sub Worksheet_Change(ByVal Target As Range)
Application.Calculate
End Sub
There's fairly good chance that the add in also snuffs events by setting application.enableEvents = false which means this won't work, but... it's worth a shot.
I'm currently learning Access 2016 since i find it works wonders with Excel.
However i'm trying to find the correct SQL code for detecting certain words in Long Text and only output these words not the text itself
Here is the setup
Fieldname: Type
Long Text
Cell Information
Cell1: Johan have a nice car
Cell2: Jane road a bike.
Cell3: Janes bike was red
Output
Cell1: car
Cell2: bike
Cell3: bike
I'm only interested in keeping certain words from these strings when the query is done, and they should be output to the same Fieldname, i have tried to locate this information for the most part of the day and my last hope of sanity was to check in here if someone has an idea of which function i should be using.
Thank you for your time
You will probably have to use VBA for this, depending on how big your list of words is, but one way to do it with SQL, assuming a relatively small and FIXED list of words:
IIF(<Mytext> LIKE '*car*','car',IIF(<Mytext> LIKE '*bike*','bike',''))
You could either read the values from a table or fill an array. Both would work, but I prefer table-driven code because, for something like this, adding new search terms would only require you to add them to your table.
So, what I would do is first create a new table called tblSearchTerms. In that table, create one field called SearchTerms, and put each of your terms (i.e. "Car", "Bike", etc...) in there, one per record.
Then set up a function in Access. Open a Module (either a new one or one you already have, as long as it's a Module), and enter this:
Function SearchExists(sString As String) As String
Dim db as Database
Dim rec as Recordset
Set db = CurrentDB
Set rec = db.OpenRecordset("Select SearchTerms from tblSearchTerms")
Do while rec.EOF = False
If InStr(1, sString, rec(0)) > 0 Then
SearchExists = "" & rec(0) & ""
Goto BugOut
Else
End If
Loop
SearchExists = "Not Found"
BugOut:
End Function
Now, what you do is create a query. In that query, you'll have one field to check to see if your search term exists. It will look something like this:
MySearchTerm: SearchExists([Cell1])
When you run your query, that field will either populate with one of the search terms (if it's found), or will return "Not Found".
This may require a bit of tweaking, because it's more for finding a search term in an Access table, so there's going to need to be some adjusting to make it work with Excel, but it's pretty close to what you need.
First, some context: I am used to working with Excel, and I have been using it to create production calculators for my worldbuilding hobby. Due to some recent problems with excessive amounts of data needing calculation, I have finally given in and tried switching it all into Access.
I have been doing some readings on how to use Access, and based on that I decided on the following:
1) I have a temperature table for regions (boreal, temperate...) with specific production levels (1,2...)
2) I have a precipitation table for regions (wet, arid...) with specific production levels (1, 2...)
3) I then have a biome table where I mix the above regions to create my biomes with the following fields:
- Biome.
- Precipitation (dropdown menu from table 2).
- Temperature (dropdown menu from table 1).
- Productivity level (which should be Precipitation Production Level from Table 2 times the Temperature Production Level from Table 1).
QUESTION: How can I have the Productivity Level in table 3 be automatic?
NOTE 1: I don't know VBA and this is my first time working with Access.
NOTE 2: I habe been told to just create table 3 as a form, but I do not think that works with what I want to do. Just in case it may be relevant (and I am not seeing the obvious), I'll next describe my first goal at building this database.
DATA ENTRY FORM: all the tables referenced below are connected by the concatenation of latitude-longitude. I have only built it partially (main form and city subform) successfully.
- main form based on table with 3 fields: latitude, longitude, terrain.
- subform based on table with 3 fields: city name, foundation date, collapse date.
- 3 subforms based on 3 tables, each representing a time period, with 2 fields: biome (biomes change in a given area depending on time periods), and its productivity levels.
After building the world, coordinate by coordinate, I will then go to the next phase - creating tables where I identify plants and animals, plus products derived from them and their levels of productivity. This will then be used to create my world's economy system and a list of characters in different levels of wealth.
I can make this work somewhat easily in Excel (without using VBA), but the amount of data will kill the file before I can use it. I only hope I'll manage to pull it off in Access - but I'll deal with this monster one step at a time. Right now, I am just focusing on the question I posted above. Thank you for any assistance you may be able to give me.
You want a database trigger meaning that entering data into biome table in the specified columns "triggers" the calculation for your third table. Access does not support triggers but there is a workaround. You use a form and create events to the textboxes of the triggering attributes.
Create a new form based on your biome table. I suggest you get the triggers to work first. Later you can add it to your form with all the subforms. Since you are new to Access you do not want to deal with subforms so soon because they make everything more complicated than it needs to be.
You rename the textboxes Precipitation, Temperature, ProductivityLevel to something like txtPrecipitation txtTemperature txtProdLevel
You open the VBA-Editor and try the following code in your new form:
.
'Trigger Events
private sub txtTemperature_Change()
call CalculateProductivityLevel()
end sub
private sub txtPrecipitation_Change()
call CalculateProductivityLevel()
end sub
private sub txtTemperature_AfterUpdate()
call CalculateProductivityLevel()
end sub
private sub txtPrecipitation_AfterUpdate()
call CalculateProductivityLevel()
end sub
'Calculation Procedure
private sub CalculateProductivityLevel()
'Check if both attributes have values. If not do not calculate anything
if (Len(me.txtTemperature & "") = 0) OR (Len(me.txtPreciperation & "") = 0) Then
exit sub
else
me.txtProdLevel = me.txtTemperature * me.txtTemperature
end sub
Note
The trigger events will call the calulcation procedure when there are new entries in the two attributes or new entries are saved.
Make sure to put the code in the new form tab of your VBA-editor
untested code so there might be some errors
The 1,500 page Access 97 Bible (don't laugh!) that I've been given by my boss to solve his problem doesn't solve my problem of how to solve his problem, because it has nee VBA code.
Let me first make clear that I've made attempts to solve this without (much) coding, and that I've coded quite a bit in VBA already, so I'm basically familiar with most things including recordsets, queries, etc etc but have problems with MS Access limits on how to form a report with data coming from VBA variables. I'm also versatile in most programming languages, but this is not a language problem but rather a "how to/what's possible" problem.
My problem right now is that dragging the query fields into the Detail subform and putting them into cells in columns setting Left and Top with VBA code are moving them alright, but each cell is on a new page. Unfortunately, there is multiple data in each cell that won't conform to the Create Report Guide options available.
So my question is simply this: Can someone point me to working examples of code that create, place, and fill with VBA variable strings, text fields at any coordinate I please on a paper size of my choice?
Edit: The above is not an option, as I understand this will prohibit the client from getting an .mde database. What remains, then, is to merely ask for some sound advice on how to get several rows GROUPed BY weekday and machine (see below) into a recordset or similar for each cell. I guess the best way is to count the number of columns in the table (machines in the sql result) and create 5 rows of these with dummy data, then go through the result rows and place the data in the relevant controls. But if you have ideas for doing this work better and faster, write them as answers.
Sorry for this, I knew there was something I wasn't understanding. Basically, I thought Access supported creating reports dynamically via VBA, ie. "generating pages with data" rather than "preparing a flow of controls connected to datasources". But Access requires that you create an ample amount of dummy, unlinked controls manually, then either fill or hide them and that's how they become "dynamic".
This is for Access 2003 on a remote server accessing local and remote ODBC SQL database tables, if relevant. The goal is to make a week schedule of n columns (n=number of machines at a certain plant) x 5 rows (weekday Mon-Fri), and put 1 or more recordset rows (=scheduled activities for that day on that machine) in each of the "n by 5 table" cells.
If you detect venting frustration in this post I can only ask your forgiveness and hope for your understanding.
So, has many techniques for this:
Ex: 1) using dinamic sql for this:
'Create a function to make sql query
Function MakeMySQlReport(Parameters):
Dim strSql as string
Dim strMyVar as string
strsql = vbnullstring
strsql = "Select " & myVar1 & " as MyFieldVar1, * from myTable where Fieldx =" & Parameters
MyReport.recordSource = ssql
End Function
Ex: 2) create function that returns yours strings:
Function MyString1() as string
MyString1 = 'ABC'
end Function
An in your report, select the textbox will receive the value and type =MyString1()]
I hope this help to you, need more examples?
Solution:
Create many objects manually (grr!)
name them systematically
put them in a Control Array (get all Me.Controls, sift out the ones you're interested in, and put them in an indexed array)
go through the array and change their properties