AnAdventurer Posted November 3, 2016 Share Posted November 3, 2016 Hello! I've attached some code below and I was wondering if there was a way to make it run faster. What it does: It detects color changes under the mouse and if the color changes it right clicks, presses E (the copy shortcut on google chrome) and pastes what it copied into an excel document. What it's for: Social media sites usually have their specific background color which will be specified by $Color. Using this code I can hover over a users display picture and it copies their name/link to their profile and pastes it into an excel document for later use. What I want: At the moment it seems to have a short delay between moving the mouse over a picture and having it execute the code. Ideally I want to be able to scroll through a page and grab every user that my mouse had landed on. It doesn't matter to me if it copies the same user multiple times due to multiple pixels on their avatar because I can remove duplicates later. Is there anything you guys can recommend to speed up the script or is this strictly a hardware/AutoIt limitation? Also, I know that it would be much faster to use IE functions for this type of thing but I am not at that skill level yet and this helps me until I get there! Thank you very much! I am looking forward to your replies! HotKeySet("{esc}","Stop") Opt ("WinTitleMatchMode", 2) Func Stop() Exit EndFunc $Color = 00000000 While 1 $MGP=MouseGetPos() $PGC=PixelGetColor($MGP[0],$MGP[1]) If $PGC <> $Color Then DoStuff() WEnd Func DoStuff() MouseClick("right",$MGP[0],$MGP[1]) Send ( "e" ) ControlSend ("Test", "", "EXCEL71", "^{v}") ControlSend ("Test", "", "EXCEL71", "{enter}") EndFunc Link to comment Share on other sites More sharing options...
j0kky Posted November 3, 2016 Share Posted November 3, 2016 (edited) Maybe your script can take advantage exatly from avoiding to copy the same user lots of times, you can do it simply taking a "memory" of the last color. The script seems to be optimized... it is just an idea, but if you notice a function which takes more time than other ones, maybe you can speed up it executing externally to your script, for example (I don't know if there is a real time benefit, you must check it through TimerInit and TimerDiff) : Run(@AutoItExe & ' /AutoIt3ExecuteLine "ControlSend (''Test'', '''', ''EXCEL71'', ''^{v}'')"') Edited November 3, 2016 by j0kky Spoiler Some UDFs I created: Winsock UDF STUN UDF WinApi_GetAdaptersAddresses _WinApi_GetLogicalProcessorInformation Bitwise with 64 bit integers An useful collection of zipping file UDFs Link to comment Share on other sites More sharing options...
AutoBert Posted November 3, 2016 Share Posted November 3, 2016 Read about the excel.au3 in helpfile and wiki Link to comment Share on other sites More sharing options...
AnAdventurer Posted November 4, 2016 Author Share Posted November 4, 2016 16 hours ago, AutoBert said: Read about the excel.au3 in helpfile and wiki Way ahead of you there! It took me more time than I care to admit to figure out how to get _Excel_Open to work and even more to get a simple value entered into a cell! I am currently stuck on getting the paste to work. Using the following code: _Excel_RangeCopyPaste($oWorkBook.ActiveSheet,Default,"A7") I keep getting error code 4: Error occurred when pasting cells using a Msgbox to display an error while the console is not showing any errors. I've also checked to see if there is a value in the clipboard with ClipGet and there is. Just to clarify, if I have the word "Test" typed in cell A1 and I change the script to: _Excel_RangeCopyPaste($oWorkBook.ActiveSheet,"A1","A7") Then "Test" is written to cell A7 so everything works except for pasting from clipboard. I am probably missing something very obvious that will come to me if I stare at it for another hour but I would appreciate it if you could point me in the right direction! My overall script seems to be slowed down by the control send so this should technically make it much faster/cleaner! Thank you once again! Link to comment Share on other sites More sharing options...
AnAdventurer Posted November 4, 2016 Author Share Posted November 4, 2016 20 hours ago, j0kky said: Maybe your script can take advantage exatly from avoiding to copy the same user lots of times, you can do it simply taking a "memory" of the last color. The script seems to be optimized... it is just an idea, but if you notice a function which takes more time than other ones, maybe you can speed up it executing externally to your script, for example (I don't know if there is a real time benefit, you must check it through TimerInit and TimerDiff) : Run(@AutoItExe & ' /AutoIt3ExecuteLine "ControlSend (''Test'', '''', ''EXCEL71'', ''^{v}'')"') I've noticed that it was the control send function that takes the most time! As AutoBert mentioned above, I've started to look at Excel functions to try and avoid doing a control send. Link to comment Share on other sites More sharing options...
AnAdventurer Posted November 6, 2016 Author Share Posted November 6, 2016 So I wasn't able to use the RangeCopyPaste command but I was able to simulate a paste using the following code: $Paste = ClipGet() _Excel_RangeWrite($oWorkBook,Default,$Paste,"A1") Now, how would I go about changing the A1 to A2, A3, A4... and so on after every paste? Link to comment Share on other sites More sharing options...
AnAdventurer Posted November 6, 2016 Author Share Posted November 6, 2016 So I've figured out that I could use a step to change the cells using this code : For $Step = 1 to 10 $Here = "A" & $Step This is what my current function looks like: Func DoStuff() MouseClick("right",$MGP[0],$MGP[1]) Send ( "e" ) For $Step = 1 to 10 $Here = "A" & $Step _Excel_RangeWrite($oWorkBook,Default,$Paste,$Here) Next EndFunc It's getting close but it's not quite there yet! There's a lot of weird stuff happening depending on where in the script I move the step to. I'll keep trying but do let me know if you have a better method of doing this! I want it to step only after it pastes and gets the next value. Also, I am having an odd interaction between the While loop and the For loop. After I added the For loop my script only runs the Do Stuff function once instead of every time I find a different pixel. Link to comment Share on other sites More sharing options...
aiter Posted November 6, 2016 Share Posted November 6, 2016 How about just putting your output into an array instead of putting into excel straight away? At the end, write the array to a text file using _FileWriteFromArray and then import the the text file into excel using _Excel_BookOpenText. Link to comment Share on other sites More sharing options...
kylomas Posted November 6, 2016 Share Posted November 6, 2016 9 minutes ago, aiter said: At the end, write the array to a text file using _FileWriteFromArray and then import the the text file into excel using _Excel_BookOpenText. Skip the interim step... See example #3 under _excel_rangewrite aiter 1 Forum Rules Procedure for posting code "I like pigs. Dogs look up to us. Cats look down on us. Pigs treat us as equals." - Sir Winston Churchill Link to comment Share on other sites More sharing options...
AnAdventurer Posted November 6, 2016 Author Share Posted November 6, 2016 Hmm, the Array idea is interesting. It automatically adds to the end of the list which is exactly what I need! I'll play around with it tomorrow. The only issue I might run into using an array would be having to limit the amount of names I get per use. My original script can go forever in one Excel document while if I paste in an array I would have to move all the names before starting to get more names or it will paste on top of the first names. I'll get back to you two when I have some time to experiment! I just want to say thank you to everyone replying. I know that all of these scripts are kinda pointless but this is really helping me learn the basics! Link to comment Share on other sites More sharing options...
AnAdventurer Posted November 9, 2016 Author Share Posted November 9, 2016 So after some playing around with it I have the following script. While 1 WinActivate("Test") $MGP=MouseGetPos() $PGC=PixelGetColor($MGP[0],$MGP[1]) If $PGC <> $Color Then DoStuff() WEnd Func DoStuff() MouseClick("right",$MGP[0],$MGP[1]) Send ( "e" ) _ArrayAdd($MyArray,ClipGet()) EndFunc Func Paste() _Excel_RangeWrite($oWorkbook, $oWorkbook.Activesheet, $MyArray, "A1") EndFunc I had to create a separate function for the range write because it kept over writing what was already there as I thought it would. For the most part it is now doing what I wanted it to do. The only thing left to improve would be getting the script to write to next empty cell as new lines are added to the array or have a way to view the array in real time just so I know how fast I can go from user to user. Also, making the loop into a function would be much better as at the moment if I quit the program and start it up again it opens up a new spreadsheet without saving the old one but these are all little things that can be done for a final release type of thing which I have no plans on doing. Once again I want to say thank you for all your help with this project! It sure beats my old mouse click, scroll down macro that I was using for this before! Next up, do this entire thing all over again but using IE functions and remove all GUI interaction! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now